├── .gitignore ├── Golang ├── iotpush-data.txt ├── iotpush-config.json └── go-client.go ├── README.md ├── JQuery └── jquery-client.js ├── Nodes.JS └── node.js-client.js ├── Python ├── python-client-telnet.py └── python-client-http.py ├── Java └── OpenTsdbJavaExample.java ├── C ├── c-client.c └── dht11-iotlab.c └── LICENSE /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | *.iml 3 | -------------------------------------------------------------------------------- /Golang/iotpush-data.txt: -------------------------------------------------------------------------------- 1 | home.temp.indoor 1437591600 22.5 source=dht22 2 | home.temp.outdoor 1437591600 28.2 source=ds18b20 3 | home.temp.indoor 1437593400 22.1 source=dht22 4 | home.temp.outdoor 1437593400 27.1 source=ds18b20 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This repository contains examples of how to push data to the Runabove IoT metrics storage in different languages. 2 | 3 | The metrics storage uses the OpenTSDB API, and read-made libraries already exist in most languages. 4 | -------------------------------------------------------------------------------- /Golang/iotpush-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "dataFile":"iotpush-data.txt", 3 | "sendType":"tls", 4 | "endPoint":"opentsdb-internal.iot.runabove.io:4243", 5 | "tokenId":"w3eaaaqaa7pff", 6 | "tokenKey":"xyz123xyz123xyz123xyz123", 7 | "tagList":{ 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /JQuery/jquery-client.js: -------------------------------------------------------------------------------- 1 | /** 2 | * JQuery sample code to put data in IoT Lab using a http session 3 | */ 4 | 5 | var TOKEN_ID = "w3eaaaqaa7pff"; // Your token id goes here 6 | var TOKEN_KEY = "xyz123xyz123xyz123xyz123"; // your token key goes here 7 | 8 | // Data object to send 9 | var data = 10 | [{ 11 | metric:"home.temp.indoor", 12 | timestamp:1437591600, 13 | value:22.5, 14 | tags:{ 15 | source:"dht22" 16 | } 17 | }, 18 | { 19 | metric:"home.temp.outdoor", 20 | timestamp:1437591600, 21 | value:28.2, 22 | tags:{ 23 | source:"ds18b20" 24 | } 25 | }, 26 | { 27 | metric:"home.temp.indoor", 28 | timestamp:1437593400, 29 | value:22.1, 30 | tags:{ 31 | source:"dht22" 32 | } 33 | }, 34 | { 35 | metric:"home.temp.outdoor", 36 | timestamp:1437593400, 37 | value:27.1, 38 | tags:{ 39 | source:"ds18b20" 40 | } 41 | }]; 42 | 43 | // Use Ajax POST method to send data to the IoT Lab OpenTSDB 44 | $.ajax("https://opentsdb.iot.runabove.io/api/put", { 45 | method: "POST", 46 | contentType: "application/json", 47 | beforeSend: function (xhr) { 48 | xhr.setRequestHeader ("Authorization", "Basic "+btoa(TOKEN_ID+":"+TOKEN_KEY)); 49 | }, 50 | data: JSON.stringify(data) 51 | }).then(function () { 52 | alert("Success!"); 53 | }, function (error) { 54 | alert("Error: " + error.responseText); 55 | }); 56 | -------------------------------------------------------------------------------- /Nodes.JS/node.js-client.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Nodes.js sample code to put data in IoT Lab using a http session 3 | */ 4 | 5 | // Library required to execute POST requests 6 | var request = require("request"); 7 | 8 | var TOKEN_ID = "w3eaaaqaa7pff"; // Your token id goes here 9 | var TOKEN_KEY = "xyz123xyz123xyz123xyz123"; // your token goes here 10 | 11 | // Data object to send 12 | var data = [{ 13 | metric:"home.temp.indoor", 14 | timestamp:1437591600, 15 | value:22.5, 16 | tags:{ 17 | source:"dht22" 18 | } 19 | }, 20 | { 21 | metric:"home.temp.outdoor", 22 | timestamp:1437591600, 23 | value:28.2, 24 | tags:{ 25 | source:"ds18b20" 26 | } 27 | }, 28 | { 29 | metric:"home.temp.indoor", 30 | timestamp:1437593400, 31 | value:22.1, 32 | tags:{ 33 | source:"dht22" 34 | } 35 | }, 36 | { 37 | metric:"home.temp.outdoor", 38 | timestamp:1437593400, 39 | value:27.1, 40 | tags:{ 41 | source:"ds18b20" 42 | } 43 | }]; 44 | 45 | 46 | // Send post request to the IoT Lab OpenTSDB 47 | request({ 48 | uri: "https://opentsdb.iot.runabove.io/api/put", 49 | auth: { 50 | user: TOKEN_ID, 51 | pass: TOKEN_KEY, 52 | sendImmediately: true 53 | }, 54 | method: "POST", 55 | json: data 56 | }, function (error, response, body) { 57 | if (error) { 58 | console.log(error); 59 | } else if (response.statusCode >= 400) { 60 | console.log(body); 61 | console.log(response.statusMessage); 62 | } else { 63 | console.log("Success!"); 64 | } 65 | }); 66 | -------------------------------------------------------------------------------- /Python/python-client-telnet.py: -------------------------------------------------------------------------------- 1 | ####################################################### 2 | # OpenTSDB telnet session in a TLS connection example # 3 | ####################################################### 4 | 5 | from socket import socket, AF_INET, SOCK_STREAM, SHUT_RDWR 6 | from ssl import wrap_socket, PROTOCOL_TLSv1 7 | 8 | # Place your token here 9 | token_id = 'w3eaaaqaa7pff' 10 | token_key = 'iXcn9sUXtKT87B6L4vYA1Asv' 11 | opentsdb_host = 'opentsdb.iot.runabove.io' 12 | opentsdb_port = 4243 13 | 14 | # Create socket 15 | client_socket = socket( AF_INET, SOCK_STREAM ) 16 | client_socket.settimeout(1) 17 | 18 | tls_client = wrap_socket( client_socket, ssl_version = PROTOCOL_TLSv1 ) 19 | 20 | print( 'Open connection' ) 21 | # Connect to the echo server 22 | tls_client.connect( ( opentsdb_host, opentsdb_port ) ) 23 | 24 | print( 'Authenticate' ) 25 | # Send auth command 26 | tls_client.send( 'auth {}:{}\n'.format( token_id, token_key ) ) 27 | 28 | # Read data received 29 | data_in = tls_client.recv( 1024 ) 30 | 31 | # Decode and print message 32 | response = data_in.decode() 33 | print( 'Read response: ' + response ) 34 | 35 | # Send data (replace metric, timestamp, data and tags with your own values) 36 | print( 'Send data' ) 37 | tls_client.send( 'put home.temp.indoor 1437591600 22.5 source=dht22\n' ) 38 | tls_client.send( 'put home.temp.outdoor 1437591600 28.2 source=ds18b20\n' ) 39 | tls_client.send( 'put home.temp.indoor 1437593400 22.1 source=dht22\n' ) 40 | tls_client.send( 'put home.temp.outdoor 1437593400 27.1 source=ds18b20\n' ) 41 | 42 | # Send exit command to close connection 43 | tls_client.send( 'exit\n' ) 44 | 45 | # Close the socket 46 | client_socket.shutdown( SHUT_RDWR ) 47 | client_socket.close() 48 | -------------------------------------------------------------------------------- /Python/python-client-http.py: -------------------------------------------------------------------------------- 1 | ########################################################### 2 | # OpenTSDB REST API session in a HTTPS connection example # 3 | ########################################################### 4 | 5 | import json 6 | import requests 7 | 8 | # Place your token id here 9 | token_id = 'w3eaaaqaa7pff' 10 | 11 | # Place your token here 12 | token_key = 'xyz123xyz123xyz123xyz123' 13 | 14 | # IoT Lab OpenTSDB Endpoint 15 | end_point = 'https://opentsdb.iot.runabove.io/api/put' 16 | 17 | # Raw body data to send 18 | data = [{ 19 | 'metric':'home.temp.indoor', 20 | 'timestamp':1437591600, 21 | 'value':22.5, 22 | 'tags':{ 23 | 'source':'dht22' 24 | } 25 | }, 26 | { 27 | 'metric':'home.temp.outdoor', 28 | 'timestamp':1437591600, 29 | 'value':28.2, 30 | 'tags':{ 31 | 'source':'ds18b20' 32 | } 33 | }, 34 | { 35 | 'metric':'home.temp.indoor', 36 | 'timestamp':1437593400, 37 | 'value':22.1, 38 | 'tags':{ 39 | 'source':'dht22' 40 | } 41 | }, 42 | { 43 | 'metric':'home.temp.outdoor', 44 | 'timestamp':1437593400, 45 | 'value':27.1, 46 | 'tags':{ 47 | 'source':'ds18b20' 48 | } 49 | }] 50 | 51 | try: 52 | # Create http session 53 | session = requests.session() 54 | 55 | # Send request and fetch response 56 | response = session.post(end_point, data=json.dumps(data), auth=(token_id, token_key)) 57 | 58 | # raise error 59 | response.raise_for_status() 60 | 61 | # Print the http response code on success 62 | print( 'Send successful\nResponse code from server:{} '.format( response.status_code ) ) 63 | 64 | except requests.exceptions.HTTPError as e: 65 | print( 'HTTP code is {} and reason is {}'.format( e.response.status_code, e.response.reason ) ) 66 | -------------------------------------------------------------------------------- /Java/OpenTsdbJavaExample.java: -------------------------------------------------------------------------------- 1 | /** 2 | * OpenTSDB data push example in Java 3 | * Push data using a telnet-tls session or a https session 4 | * Requires Java 8 because of the use of java.util.Base64 package 5 | * 6 | * To run the program with the OpenJRE VM, you can use the command 7 | * java OpenTsdbJavaExample -https 8 | * or 9 | * java OpenTsdbJavaExample -tls 10 | */ 11 | 12 | import javax.net.ssl.*; 13 | import java.io.*; 14 | import java.net.*; 15 | 16 | public class OpenTsdbJavaExample { 17 | 18 | /** 19 | * Put here your write token id 20 | */ 21 | private static final String TOKEN_ID = "w3eaaaqaa7pff"; 22 | 23 | /** 24 | * Put here your write token key 25 | */ 26 | private static final String TOKEN_KEY = "xyz123xyz123xyz123xyz123"; 27 | 28 | /** 29 | * Hostname of the endpoint 30 | */ 31 | private static final String OPENTSDB_SERVER = "opentsdb.iot.runabove.io"; 32 | 33 | /** 34 | * Port number for telnet session 35 | */ 36 | private static final int OPENTSDB_PORT = 4243; 37 | 38 | /** 39 | * Main method 40 | */ 41 | public static void main(String args[]) { 42 | if (args.length > 0) { 43 | if ("-tls".equals(args[0])) { 44 | OpenTsdbJavaExample.sendByTelnet(); 45 | } else if ("-https".equals(args[0])) { 46 | OpenTsdbJavaExample.sendByHttp(); 47 | } else { 48 | System.out.println("Error, method "+args[0]+" unknown, please use -https or -tls"); 49 | } 50 | } else { 51 | System.out.println("Error, no method specified, please use -https or -tls"); 52 | } 53 | } 54 | 55 | /** 56 | * OpenTSDB REST API session in a HTTPS connection example 57 | */ 58 | private static void sendByHttp() { 59 | HttpURLConnection conn = null; 60 | 61 | // Payload to send as body in json raw data 62 | // Prefer using a JSON library like org.json or Jackson to avoid any encoding problem 63 | String input = ""; 64 | input += "[{"; 65 | input += " \"metric\":\"home.temp.indoor\","; 66 | input += " \"timestamp\":1437591600,"; 67 | input += " \"value\":22.5,"; 68 | input += " \"tags\":{"; 69 | input += " \"source\":\"dht22\""; 70 | input += " }"; 71 | input += "},"; 72 | input += "{"; 73 | input += " \"metric\":\"home.temp.outdoor\","; 74 | input += " \"timestamp\":1437591600,"; 75 | input += " \"value\":28.2,"; 76 | input += " \"tags\":{"; 77 | input += " \"source\":\"ds18b20\""; 78 | input += " }"; 79 | input += "},"; 80 | input += "{"; 81 | input += " \"metric\":\"home.temp.indoor\","; 82 | input += " \"timestamp\":1437593400,"; 83 | input += " \"value\":22.1,"; 84 | input += " \"tags\":{"; 85 | input += " \"source\":\"dht22\""; 86 | input += " }"; 87 | input += "},"; 88 | input += "{"; 89 | input += " \"metric\":\"home.temp.outdoor\","; 90 | input += " \"timestamp\":1437593400,"; 91 | input += " \"value\":27.1,"; 92 | input += " \"tags\":{"; 93 | input += " \"source\":\"ds18b20\""; 94 | input += " }"; 95 | input += "}]"; 96 | 97 | try { 98 | // Initialize connection parameters 99 | URL url = new URL("https://"+OPENTSDB_SERVER+"/api/put"); 100 | conn = (HttpURLConnection) url.openConnection(); 101 | 102 | // Set HTTP Basic Auth 103 | conn.setRequestProperty("Authorization", "Basic "+java.util.Base64.getEncoder().encodeToString((TOKEN_ID+":"+TOKEN_KEY).getBytes())); 104 | 105 | conn.setDoOutput(true); 106 | conn.setRequestMethod("POST"); 107 | conn.setRequestProperty("Content-Type", "application/json"); 108 | 109 | // Send the payload as outputstream 110 | OutputStream requestBody = conn.getOutputStream(); 111 | requestBody.write(input.getBytes()); 112 | requestBody.flush(); 113 | 114 | // Parse the response from the server 115 | if (conn.getResponseCode() >= 400) { 116 | // Error from the server 117 | System.out.println("Send failed, HTTP error code : " + conn.getResponseCode()); 118 | 119 | System.out.println("Output from Server, if any:"); 120 | BufferedReader responseBody = new BufferedReader(new InputStreamReader((conn.getErrorStream()))); 121 | 122 | // Print the response body in stdout 123 | String output; 124 | while ((output = responseBody.readLine()) != null) { 125 | System.out.println(output); 126 | } 127 | } else { 128 | // No error from the server 129 | BufferedReader responseBody = new BufferedReader(new InputStreamReader((conn.getInputStream()))); 130 | 131 | // Print the response body in stdout 132 | String output; 133 | System.out.println("Send successful\nOutput from Server, if any:"); 134 | while ((output = responseBody.readLine()) != null) { 135 | System.out.println(output); 136 | } 137 | } 138 | 139 | } catch (IOException e) { 140 | System.out.println(e.getMessage()); 141 | } finally { 142 | conn.disconnect(); 143 | } 144 | } 145 | 146 | /** 147 | * OpenTSDB telnet session in a TLS connection example 148 | */ 149 | private static void sendByTelnet() { 150 | 151 | SSLSocket sslsocket = null; 152 | DataOutputStream outToServer = null; 153 | BufferedReader inFromServer = null; 154 | try { 155 | // Open the tls connection 156 | SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault(); 157 | System.out.println("Opening connection"); 158 | sslsocket = (SSLSocket) factory.createSocket(OPENTSDB_SERVER, OPENTSDB_PORT); 159 | 160 | // Initialize the read/write buffers 161 | outToServer = new DataOutputStream(sslsocket.getOutputStream()); 162 | inFromServer = new BufferedReader(new InputStreamReader(sslsocket.getInputStream())); 163 | 164 | // Send the auth command with the token 165 | outToServer.writeBytes("auth " + TOKEN_ID + ":" + TOKEN_KEY + "\n"); 166 | 167 | // Read the auth command result 168 | String responseStr; 169 | if((responseStr = inFromServer.readLine()) != null) { 170 | System.out.println("Auth response: "+responseStr); 171 | } 172 | 173 | // Send the put commands and exit 174 | outToServer.writeBytes("put home.temp.indoor 1437591600 22.5 source=dht22\n"); 175 | outToServer.writeBytes("put home.temp.outdoor 1437591600 28.2 source=ds18b20\n"); 176 | outToServer.writeBytes("put home.temp.indoor 1437593400 22.1 source=dht22\n"); 177 | outToServer.writeBytes("put home.temp.outdoor 1437593400 27.1 source=ds18b20\n"); 178 | outToServer.writeBytes("exit\n"); 179 | 180 | // Read the response from the server 181 | if((responseStr = inFromServer.readLine()) != null) { 182 | System.out.println("Message from server: " + responseStr); 183 | } else { 184 | System.out.println("Send complete"); 185 | } 186 | 187 | } catch(IOException e) { 188 | System.out.println(e.getMessage()); 189 | } finally { 190 | // Close the connection and the read and write buffers 191 | try { 192 | if (outToServer != null) { 193 | outToServer.close(); 194 | } 195 | } catch (IOException e) { 196 | System.out.println(e.getMessage()); 197 | } 198 | 199 | try { 200 | if (inFromServer != null) { 201 | inFromServer.close(); 202 | } 203 | } catch (IOException e) { 204 | System.out.println(e.getMessage()); 205 | } 206 | 207 | try { 208 | if (sslsocket != null) { 209 | sslsocket.close(); 210 | } 211 | } catch (IOException e) { 212 | System.out.println(e.getMessage()); 213 | } 214 | } 215 | } 216 | } 217 | -------------------------------------------------------------------------------- /Golang/go-client.go: -------------------------------------------------------------------------------- 1 | // OpenTSDB data push example in Go lang 2 | // Push data using a telnet-tls session or a https session 3 | // 4 | // The parameters are set in the file iotpush-config.json and the data file specified by the configuration 5 | // in this example, the data file is iotpush-data.txt 6 | // 7 | // iotpush-config.json parameters: 8 | // - dataFile: the path to the data file 9 | // - sendType: type of protocol used, https or tls 10 | // - endPoint: the address of the endpoint, for example opentsdb-internal.iot.runabove.io:4243 for a telnet session or https://opentsdb.iot.runabove.io/api/put for a http session 11 | // - tokenWrite: A valid IoT Lab WRITE token 12 | // - tagList: A list of tags that will be added to all values put, format key:value 13 | // 14 | // data file format: 15 | // 16 | // - metric: the metric name to use for this data 17 | // - timestamp: the timestamp of the data in Unix Epoch format in seconds 18 | // - value: the value of the data 19 | // - additional tags: any additional tag you want to add to your data 20 | package main 21 | 22 | import ( 23 | "bufio" 24 | "bytes" 25 | "crypto/tls" 26 | "encoding/json" 27 | "errors" 28 | "fmt" 29 | "io/ioutil" 30 | "net" 31 | "net/http" 32 | "os" 33 | "strconv" 34 | "strings" 35 | "time" 36 | ) 37 | 38 | // Structure of the config file 39 | type Config struct { 40 | Endpoint string `json:"endPoint"` // url of the endpoint 41 | TokenId string `json:"tokenId"` // Write token id 42 | TokenKey string `json:"tokenKey"` // Token key 43 | TagList map[string]string `json:"tagList"` // a list of tags to add to all put values 44 | SendType string `json:"sendType"` // send type (https or tls) 45 | DataFile string `json:"dataFile"` // file containing the data to send 46 | } 47 | 48 | // Structure of the data file 49 | type Data struct { 50 | MetricName string `json:"metric"` // Metric value 51 | Timestamp int64 `json:"timestamp"` // Timestamp in Unix Epoch format in seconds 52 | Data float64 `json:"value"` // Data payload 53 | TagList map[string]string `json:"tags"` // a list of tags to add to this payload 54 | } 55 | 56 | // Main function 57 | func main() { 58 | // Open the file iotpush.conf in the same directory 59 | config, err := getConfig("iotpush-config.json") 60 | 61 | if err == nil { 62 | if dataList, err := getData(config); err == nil { 63 | // Checks the SendType option and use the proper function 64 | if config.SendType == "tls" { 65 | fmt.Println("type tls") 66 | if err = SendByTelnet(dataList, config.Endpoint, config.TokenId, config.TokenKey); err == nil { 67 | fmt.Println("Send complete") 68 | } else { 69 | fmt.Println(err) 70 | } 71 | } else if config.SendType == "https" { 72 | fmt.Println("type https") 73 | if err = SendByHttp(dataList, fmt.Sprint("https://", config.Endpoint, "/api/put"), config.TokenId, config.TokenKey); err == nil { 74 | fmt.Println("Send complete") 75 | } else { 76 | fmt.Println(err) 77 | } 78 | } else { 79 | fmt.Println("Error, send type unknown") 80 | } 81 | } else { 82 | fmt.Println(err) 83 | } 84 | } else { 85 | fmt.Println(err) 86 | } 87 | } 88 | 89 | // Open the config file and return the parsed configuration 90 | func getConfig(configFile string) (*Config, error) { 91 | var config Config 92 | 93 | data, err := ioutil.ReadFile(configFile) 94 | if err != nil { 95 | return nil, errors.New(fmt.Sprint("Error reading config file, ", err)) 96 | } 97 | 98 | if err = json.Unmarshal(data, &config); err == nil { 99 | return &config, nil 100 | } else { 101 | return nil, errors.New(fmt.Sprint("Error loading config file, ", err)) 102 | } 103 | } 104 | 105 | // Open the data file and return the parsed payload 106 | func getData(config *Config) ([]Data, error) { 107 | inFile, err := os.Open(config.DataFile) 108 | if err != nil { 109 | return nil, errors.New(fmt.Sprint("Error reading data file: ", err)) 110 | } 111 | var dataList []Data 112 | defer inFile.Close() 113 | scanner := bufio.NewScanner(inFile) 114 | scanner.Split(bufio.ScanLines) 115 | 116 | for scanner.Scan() { 117 | if oneLine := strings.Split(scanner.Text(), " "); len(oneLine) >= 3 { 118 | // Line must contain a metric name, a timestamp in UNIX EPOCH format, and a value 119 | var toAppend = true 120 | var oneData Data 121 | oneData.TagList = make(map[string]string) 122 | for key, value := range config.TagList { 123 | oneData.TagList[key] = value 124 | } 125 | for i, elt := range oneLine { 126 | if i == 0 { 127 | // Metric name 128 | oneData.MetricName = elt 129 | } else if i == 1 { 130 | // Epoch timestamp 131 | oneData.Timestamp, err = strconv.ParseInt(elt, 10, 64) 132 | if err != nil { 133 | oneData.Timestamp = time.Now().Unix() 134 | } 135 | } else if i == 2 { 136 | // data 137 | oneData.Data, err = strconv.ParseFloat(elt, 64) 138 | if err != nil { 139 | toAppend = false 140 | } 141 | } else { 142 | // tag (format key=value) 143 | oneTag := strings.Split(elt, "=") 144 | if len(oneTag) == 2 { 145 | oneData.TagList[oneTag[0]] = oneTag[1] 146 | } 147 | } 148 | } 149 | if toAppend { 150 | dataList = append(dataList, oneData) 151 | } 152 | } 153 | } 154 | return dataList, nil 155 | } 156 | 157 | // Converts a tag list to a string 158 | func TagListToString(tagList map[string]string) string { 159 | values := make([]string, 0, len(tagList)) 160 | for key, value := range tagList { 161 | values = append(values, fmt.Sprintf("%s=%s", key, value)) 162 | } 163 | return strings.Join(values, " ") 164 | } 165 | 166 | // Push data using a telnet tls session 167 | func SendByTelnet(dataList []Data, endpoint string, tokenId string, tokenKey string) error { 168 | host, _, err := net.SplitHostPort(endpoint) 169 | if err != nil { 170 | return err 171 | } 172 | 173 | var readLine []byte 174 | tlc := &tls.Config{ 175 | ServerName: host, 176 | } 177 | 178 | fmt.Println("Open connection") 179 | connTls, err := tls.Dial("tcp", endpoint, tlc) 180 | defer connTls.Close() 181 | 182 | if err != nil { 183 | return errors.New(fmt.Sprint("Error opening connexion:", err)) 184 | } 185 | 186 | fmt.Println("Connection open, sending auth command") 187 | putLine := fmt.Sprintf("auth %s:%s\n", tokenId, tokenKey) 188 | fmt.Fprintf(connTls, putLine) 189 | 190 | message, err := bufio.NewReader(connTls).ReadString('\n') 191 | if err != nil { 192 | return err 193 | } 194 | 195 | fmt.Print("Response to auth command: ", message) 196 | for _, oneData := range dataList { 197 | putLine := fmt.Sprintf("put %s %d %f %s\n", oneData.MetricName, oneData.Timestamp, oneData.Data, TagListToString(oneData.TagList)) 198 | fmt.Fprintf(connTls, putLine) 199 | 200 | length, err := bufio.NewReader(connTls).Read(readLine) 201 | if err != nil { 202 | return err 203 | } 204 | 205 | if length > 0 { 206 | fmt.Println(fmt.Sprint("Error pushing data", putLine, "response is: ", string(readLine))) 207 | } 208 | } 209 | fmt.Fprintf(connTls, "exit\n") 210 | return nil 211 | } 212 | 213 | // Push the data using the OpenTSDB REST API 214 | func SendByHttp(dataList []Data, endpoint string, tokenId string, tokenKey string) error { 215 | 216 | var err error 217 | client := http.Client{} 218 | b := make([]byte, 0) 219 | if dataList != nil { 220 | b, err = json.Marshal(dataList) 221 | if err != nil { 222 | return err 223 | } 224 | } 225 | 226 | req, err := http.NewRequest("POST", endpoint, bytes.NewReader(b)) 227 | if err == nil { 228 | req.SetBasicAuth(tokenId, tokenKey) 229 | resp, err := client.Do(req) 230 | defer resp.Body.Close() 231 | 232 | if err != nil { 233 | return err 234 | } 235 | 236 | body, err := ioutil.ReadAll(resp.Body) 237 | if err != nil { 238 | return err 239 | } 240 | fmt.Println(fmt.Sprintf("Response from server (if any): %s", string(body))) 241 | } 242 | return err 243 | } 244 | -------------------------------------------------------------------------------- /C/c-client.c: -------------------------------------------------------------------------------- 1 | /** 2 | * OpenTSDB data push example in C using the libraries ssl, crypto and libcurl 3 | * Push data using a telnet-tls session or a https session 4 | * 5 | * To compile using gcc, run the following command: 6 | * gcc -o c-client c-client.c -lssl -lcrypto -lcurl 7 | * 8 | * To run the program, use the following commands 9 | * '$ ./c-client -https' or '$ ./c-client -tls' 10 | */ 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | 28 | // Simple structure to keep track of the handle, and 29 | // of what needs to be freed later. 30 | typedef struct { 31 | int socket; 32 | SSL *sslHandle; 33 | SSL_CTX *sslContext; 34 | } connection; 35 | 36 | // We'll be connecting to opentsdb.iot.runabove.io 37 | #define IOT_SERVER "opentsdb.iot.runabove.io" 38 | 39 | // Port 4243 for tls connection 40 | #define TELNET_PORT 4243 41 | 42 | // Put here your write token id 43 | #define TOKEN_ID "w3eaaaqaa7pff" 44 | 45 | // Put here your token key 46 | #define TOKEN_KEY "xyz123xyz123xyz123xyz123" 47 | 48 | // Establish a regular tcp connection 49 | int tcpConnect () { 50 | int error, handle; 51 | struct hostent *host; 52 | struct sockaddr_in server; 53 | 54 | host = gethostbyname (IOT_SERVER); 55 | handle = socket (AF_INET, SOCK_STREAM, 0); 56 | if (handle == -1) { 57 | perror ("Socket"); 58 | handle = 0; 59 | } else { 60 | server.sin_family = AF_INET; 61 | server.sin_port = htons (TELNET_PORT); 62 | server.sin_addr = *((struct in_addr *) host->h_addr); 63 | bzero (&(server.sin_zero), 8); 64 | 65 | error = connect (handle, (struct sockaddr *) &server, sizeof (struct sockaddr)); 66 | if (error == -1) { 67 | perror ("Connect"); 68 | handle = 0; 69 | } 70 | } 71 | 72 | return handle; 73 | } 74 | 75 | // Establish a telnet connection using an SSL layer 76 | connection *sslConnect (void) { 77 | connection *c; 78 | 79 | c = malloc (sizeof (connection)); 80 | c->sslHandle = NULL; 81 | c->sslContext = NULL; 82 | 83 | c->socket = tcpConnect (); 84 | if (c->socket) { 85 | // Register the error strings for libcrypto & libssl 86 | SSL_load_error_strings (); 87 | 88 | // Register the available ciphers and digests 89 | SSL_library_init (); 90 | 91 | // New context saying we are a client, and using SSL 2 or 3 92 | c->sslContext = SSL_CTX_new (SSLv23_client_method ()); 93 | if (c->sslContext == NULL) 94 | ERR_print_errors_fp (stderr); 95 | 96 | // Create an SSL struct for the connection 97 | c->sslHandle = SSL_new (c->sslContext); 98 | if (c->sslHandle == NULL) 99 | ERR_print_errors_fp (stderr); 100 | 101 | // Connect the SSL struct to our connection 102 | if (!SSL_set_fd (c->sslHandle, c->socket)) 103 | ERR_print_errors_fp (stderr); 104 | 105 | // Initiate SSL handshake 106 | if (SSL_connect (c->sslHandle) != 1) 107 | ERR_print_errors_fp (stderr); 108 | } else { 109 | perror ("Connect failed"); 110 | } 111 | 112 | return c; 113 | } 114 | 115 | // Disconnect & free connection struct 116 | void sslDisconnect (connection *c) { 117 | if (c->socket) 118 | close (c->socket); 119 | if (c->sslHandle) { 120 | SSL_shutdown (c->sslHandle); 121 | SSL_free (c->sslHandle); 122 | } 123 | if (c->sslContext) 124 | SSL_CTX_free (c->sslContext); 125 | 126 | free (c); 127 | } 128 | 129 | // Read all available text from the connection 130 | char *sslRead (connection *c) { 131 | const int readSize = 1024; 132 | char *rc = NULL; 133 | int received, count = 0; 134 | char buffer[1024]; 135 | 136 | if (c) { 137 | while (1) { 138 | if (!rc) { 139 | rc = malloc (readSize * sizeof (char) + 1); 140 | // Initialize rc to NULL String 141 | if (rc != NULL) 142 | rc[0] = '\0'; 143 | } else { 144 | rc = realloc (rc, (count + 1) * readSize * sizeof (char) + 1); 145 | } 146 | 147 | received = SSL_read (c->sslHandle, buffer, readSize); 148 | buffer[received] = '\0'; 149 | 150 | if (received > 0) 151 | strcat (rc, buffer); 152 | 153 | if (received < readSize) 154 | break; 155 | count++; 156 | } 157 | } 158 | 159 | return rc; 160 | } 161 | 162 | // Write text to the connection 163 | void sslWrite (connection *c, char *text) { 164 | if (c) 165 | SSL_write (c->sslHandle, text, strlen (text)); 166 | } 167 | 168 | // Send the data using a telnet session on a TLS connection 169 | void sendByTelnet() { 170 | 171 | connection *c; 172 | char *response; 173 | 174 | // Initiate the connection 175 | c = sslConnect (); 176 | 177 | // Initiate the authentication 178 | sslWrite (c, "auth " TOKEN_ID ":" TOKEN_KEY "\n"); 179 | response = sslRead (c); 180 | 181 | // Read the response from the server (should send 'ok' if the token is valid) 182 | printf ("auth command response\n %s\n", response); 183 | free (response); 184 | 185 | // Send the put commands one after the other 186 | sslWrite (c, "put home.temp.indoor 1437591600 22.5 source=dht22\n"); 187 | sslWrite (c, "put home.temp.outdoor 1437591600 28.2 source=ds18b20\n"); 188 | sslWrite (c, "put home.temp.indoor 1437593400 22.1 source=dht22\n"); 189 | sslWrite (c, "put home.temp.outdoor 1437593400 27.1 source=ds18b20\n"); 190 | sslWrite (c, "exit\n"); 191 | 192 | // Read the response from the server. No response means no error 193 | response = sslRead (c); 194 | printf ("put command response (if any)\n %s\n", response); 195 | free (response); 196 | 197 | // Disconnect from the server 198 | sslDisconnect (c); 199 | 200 | } 201 | 202 | // Send the data on a OpenTSDB REST API session using a https connection 203 | void sendByHttp() { 204 | 205 | // Use libcurl to manage the http communication 206 | CURL *curl; 207 | CURLcode res; 208 | struct curl_slist *headers = NULL; 209 | long http_code = 0; 210 | 211 | curl_global_init(CURL_GLOBAL_ALL); 212 | 213 | curl = curl_easy_init(); 214 | if(curl) { 215 | // Set header values 216 | headers = curl_slist_append(headers, "Accept: application/json"); 217 | headers = curl_slist_append(headers, "Content-Type: application/json"); 218 | curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); 219 | 220 | // Set endpoint url 221 | curl_easy_setopt(curl, CURLOPT_URL, "https://" IOT_SERVER "/api/put"); 222 | 223 | // Set verb 224 | curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST"); 225 | 226 | // Set HTTP Basic Auth 227 | curl_easy_setopt(curl, CURLOPT_USERPWD, TOKEN_ID ":" TOKEN_KEY); 228 | 229 | // Set data posted 230 | curl_easy_setopt(curl, CURLOPT_POSTFIELDS, 231 | "[{\ 232 | \"metric\":\"home.temp.indoor\",\ 233 | \"timestamp\":1437591600,\ 234 | \"value\":22.5,\ 235 | \"tags\":{\ 236 | \"source\":\"dht22\"\ 237 | }\ 238 | },\ 239 | {\ 240 | \"metric\":\"home.temp.outdoor\",\ 241 | \"timestamp\":1437591600,\ 242 | \"value\":28.2,\ 243 | \"tags\":{\ 244 | \"source\":\"ds18b20\"\ 245 | }\ 246 | },\ 247 | {\ 248 | \"metric\":\"home.temp.indoor\",\ 249 | \"timestamp\":1437593400,\ 250 | \"value\":22.1,\ 251 | \"tags\":{\ 252 | \"source\":\"dht22\"\ 253 | }\ 254 | },\ 255 | {\ 256 | \"metric\":\"home.temp.outdoor\",\ 257 | \"timestamp\":1437593400,\ 258 | \"value\":27.1,\ 259 | \"tags\":{\ 260 | \"source\":\"ds18b20\"\ 261 | }\ 262 | }]"); 263 | 264 | // Perform the connection 265 | res = curl_easy_perform(curl); 266 | if(res != CURLE_OK) { 267 | fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res)); 268 | } 269 | 270 | // Get and print the results 271 | curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &http_code); 272 | printf("response code: %ld\n", http_code); 273 | 274 | // Clean the result after use 275 | curl_easy_cleanup(curl); 276 | } 277 | 278 | // Clean all the libcurl context before quit 279 | curl_global_cleanup(); 280 | } 281 | 282 | // main function, check the cli argument and run the proper method 283 | int main (int argc, char **argv) { 284 | 285 | // Check command-line arguments 286 | if (argc >= 2) { 287 | if (strcmp(argv[1], "-tls") == 0) { 288 | sendByTelnet(); 289 | } else if (strcmp(argv[1], "-https") == 0) { 290 | sendByHttp(); 291 | } else { 292 | printf("usage %s -tls|-https\n", argv[0]); 293 | } 294 | } else { 295 | printf("usage %s -tls|-https\n", argv[0]); 296 | } 297 | return 0; 298 | } 299 | -------------------------------------------------------------------------------- /C/dht11-iotlab.c: -------------------------------------------------------------------------------- 1 | /** 2 | * dht11.c: 3 | * Read temperature and humidity from a dht11 sensor on a Raspberry pi, 4 | * then send it to the RunAbove IoT lab opentsdb server via a telnet session on a TLS connection 5 | * the metrics used are .temp and .hum with the current timestamp 6 | * 7 | * You need the libraries libssl-dev and wiringPi to compile 8 | * 9 | * Compilation: gcc -o dht11-iotlab dht11-iotlab.c -lwiringPi -lssl -lcrypto 10 | * 11 | * Usage: sudo ./dht11-iotlab [additional_tags] 12 | * 13 | */ 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | #include 28 | 29 | // We'll connect to opentsdb.iot.runabove.io 30 | #define IOT_SERVER "opentsdb.iot.runabove.io" 31 | 32 | // Port 4243 for tls connection 33 | #define TELNET_PORT 4243 34 | 35 | #define WORDLENGTH 8 36 | #define MAXTIMINGS 42 37 | 38 | // Set here the pin where you have plugged your DHT11 39 | #define DHTPIN 7 40 | 41 | int dht11_dat[5] = { 0, 0, 0, 0, 0 }; 42 | 43 | enum status{valid, invalid}; 44 | 45 | typedef struct { 46 | char hum[WORDLENGTH+1]; 47 | char temp[WORDLENGTH+1]; 48 | int status; 49 | } sensor_data; 50 | 51 | sensor_data read_dht11_dat() { 52 | uint8_t laststate = HIGH; 53 | uint8_t counter = 0; 54 | uint8_t j = 0, i; 55 | sensor_data data; 56 | 57 | dht11_dat[0] = dht11_dat[1] = dht11_dat[2] = dht11_dat[3] = dht11_dat[4] = 0; 58 | 59 | /* pull pin down for 18 milliseconds */ 60 | pinMode( DHTPIN, OUTPUT ); 61 | digitalWrite( DHTPIN, LOW ); 62 | delay( 18 ); 63 | /* then pull it up for 40 microseconds */ 64 | digitalWrite( DHTPIN, HIGH ); 65 | delayMicroseconds( 40 ); 66 | /* prepare to read the pin */ 67 | pinMode( DHTPIN, INPUT ); 68 | 69 | /* detect change and read data */ 70 | for ( i = 0; i < MAXTIMINGS; i++ ) { 71 | counter = 0; 72 | while ( digitalRead( DHTPIN ) == laststate ) { 73 | counter++; 74 | delayMicroseconds( 1 ); 75 | if ( counter == 255 ) { 76 | break; 77 | } 78 | } 79 | laststate = digitalRead( DHTPIN ); 80 | 81 | if ( counter == 255 ) 82 | break; 83 | 84 | /* ignore first 3 transitions */ 85 | if ( (i >= 4) && (i % 2 == 0) ) { 86 | /* shove each bit into the storage bytes */ 87 | dht11_dat[j / 8] <<= 1; 88 | if ( counter > 16 ) 89 | dht11_dat[j / 8] |= 1; 90 | j++; 91 | } 92 | } 93 | 94 | /** 95 | * check we read 40 bits (8bit x 5 ) + verify checksum in the last byte 96 | * set sensor_data values if data is good 97 | * set sensor_data values if data is good 98 | */ 99 | if ( (j >= 40) && (dht11_dat[4] == ( (dht11_dat[0] + dht11_dat[1] + dht11_dat[2] + dht11_dat[3]) & 0xFF) ) ) { 100 | snprintf(data.hum, WORDLENGTH, "%d.%d", dht11_dat[0], dht11_dat[1]); 101 | snprintf(data.temp, WORDLENGTH, "%d.%d", dht11_dat[2], dht11_dat[3]); 102 | data.status = valid; 103 | } else { 104 | data.status = invalid; 105 | } 106 | return data; 107 | } 108 | 109 | // Simple structure to keep track of the handle, and 110 | // of what needs to be freed later. 111 | typedef struct { 112 | int socket; 113 | SSL *sslHandle; 114 | SSL_CTX *sslContext; 115 | } ssl_connection; 116 | 117 | // Establish a regular tcp connection 118 | int tcpConnect () { 119 | int error, handle; 120 | struct hostent *host; 121 | struct sockaddr_in server; 122 | 123 | host = gethostbyname (IOT_SERVER); 124 | handle = socket (AF_INET, SOCK_STREAM, 0); 125 | if (handle == -1) { 126 | perror ("Socket"); 127 | handle = 0; 128 | } else { 129 | server.sin_family = AF_INET; 130 | server.sin_port = htons (TELNET_PORT); 131 | server.sin_addr = *((struct in_addr *) host->h_addr); 132 | bzero (&(server.sin_zero), 8); 133 | 134 | error = connect (handle, (struct sockaddr *) &server, sizeof (struct sockaddr)); 135 | if (error == -1) { 136 | perror ("Connect"); 137 | handle = 0; 138 | } 139 | } 140 | 141 | return handle; 142 | } 143 | 144 | // Establish a telnet connection using an SSL layer 145 | ssl_connection *sslConnect (void) { 146 | ssl_connection *c; 147 | 148 | c = malloc (sizeof (ssl_connection)); 149 | c->sslHandle = NULL; 150 | c->sslContext = NULL; 151 | 152 | c->socket = tcpConnect (); 153 | if (c->socket) { 154 | // Register the error strings for libcrypto & libssl 155 | SSL_load_error_strings (); 156 | 157 | // Register the available ciphers and digests 158 | SSL_library_init (); 159 | 160 | // New context saying we are a client, and using SSL 2 or 3 161 | c->sslContext = SSL_CTX_new (SSLv23_client_method ()); 162 | if (c->sslContext == NULL) 163 | ERR_print_errors_fp (stderr); 164 | 165 | // Create an SSL struct for the connection 166 | c->sslHandle = SSL_new (c->sslContext); 167 | if (c->sslHandle == NULL) 168 | ERR_print_errors_fp (stderr); 169 | 170 | // Connect the SSL struct to our connection 171 | if (!SSL_set_fd (c->sslHandle, c->socket)) 172 | ERR_print_errors_fp (stderr); 173 | 174 | // Initiate SSL handshake 175 | if (SSL_connect (c->sslHandle) != 1) 176 | ERR_print_errors_fp (stderr); 177 | } else { 178 | perror ("Connect failed"); 179 | } 180 | 181 | return c; 182 | } 183 | 184 | // Disconnect & free connection struct 185 | void sslDisconnect (ssl_connection *c) { 186 | if (c->socket) 187 | close (c->socket); 188 | if (c->sslHandle) { 189 | SSL_shutdown (c->sslHandle); 190 | SSL_free (c->sslHandle); 191 | } 192 | if (c->sslContext) 193 | SSL_CTX_free (c->sslContext); 194 | 195 | free (c); 196 | } 197 | 198 | // Read all available text from the connection 199 | char *sslRead (ssl_connection *c) { 200 | const int readSize = 1024; 201 | char *rc = NULL; 202 | int received, count = 0; 203 | char buffer[1024]; 204 | 205 | if (c) { 206 | while (1) { 207 | if (!rc) { 208 | rc = malloc (readSize * sizeof (char) + 1); 209 | // Initialize rc to NULL String 210 | if (rc != NULL) 211 | rc[0] = '\0'; 212 | } else { 213 | rc = realloc (rc, (count + 1) * readSize * sizeof (char) + 1); 214 | } 215 | 216 | received = SSL_read (c->sslHandle, buffer, readSize); 217 | buffer[received] = '\0'; 218 | 219 | if (received > 0) 220 | strcat (rc, buffer); 221 | 222 | if (received < readSize) 223 | break; 224 | count++; 225 | } 226 | } 227 | 228 | return rc; 229 | } 230 | 231 | // Write text to the connection 232 | void sslWrite (ssl_connection *c, char *text) { 233 | if (c) 234 | SSL_write (c->sslHandle, text, strlen (text)); 235 | } 236 | 237 | // Send the data using a telnet session on a TLS connection 238 | void sendByTelnet(sensor_data data, char * token, char * metric, char * additional_tags) { 239 | 240 | ssl_connection *c; 241 | char *response, *response_auth, query[1024]; 242 | time_t now; 243 | 244 | // Initiate the connection 245 | c = sslConnect (); 246 | 247 | // Initiate the authentication 248 | snprintf(query, 1023, "auth %s\n", token); 249 | sslWrite (c, query); 250 | response_auth = sslRead (c); 251 | 252 | // Read the response from the server (should send 'ok' if the token is valid) 253 | if (0 == strcmp("ok\n", response_auth)) { 254 | time(&now); 255 | 256 | // Send the put commands one after the other 257 | snprintf(query, 1023, "put %s.hum %ld %s %s\n", metric, now, data.hum, additional_tags); 258 | sslWrite (c, query); 259 | 260 | snprintf(query, 1023, "put %s.temp %ld %s %s\n", metric, now, data.temp, additional_tags); 261 | sslWrite (c, query); 262 | } else { 263 | printf("Error auth, response is %s\n", response_auth); 264 | } 265 | 266 | free (response_auth); 267 | 268 | sslWrite (c, "exit\n"); 269 | // Read the response from the server. No response means no error 270 | response = sslRead (c); 271 | if (0 != strcmp("", response)) { 272 | printf ("Command put error\n \"%s\"\n", response); 273 | } 274 | free(response); 275 | 276 | // Disconnect from the server 277 | sslDisconnect (c); 278 | } 279 | 280 | /** 281 | * Main function 282 | * 283 | * Parse the command line arguments, then every 5 minutes reads the sensor data 284 | * If the data is valid, push it to IoT lab 285 | * 286 | */ 287 | int main( int argc, char ** argv ) { 288 | char * additional_tags; 289 | size_t len = 0; 290 | int i; 291 | sensor_data data; 292 | 293 | if ( wiringPiSetup() == -1 ) 294 | exit(EXIT_FAILURE); 295 | 296 | // Parse arguments 297 | if (argc >= 3) { 298 | if (argc >= 4) { 299 | // Concat additional tags arguments in a single char* 300 | for (i=3; i