Dan Lopez / osisoft-omf
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers osisoft-omf.cpp Source File

osisoft-omf.cpp

00001 //Copyright 2018 OSIsoft, LLC
00002 //
00003 //Licensed under the Apache License, Version 2.0 (the "License");
00004 //you may not use this file except in compliance with the License.
00005 //You may obtain a copy of the License at
00006 //
00007 //<http://www.apache.org/licenses/LICENSE-2.0>
00008 //
00009 //Unless required by applicable law or agreed to in writing, software
00010 //distributed under the License is distributed on an "AS IS" BASIS,
00011 //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00012 //See the License for the specific language governing permissions and
00013 //limitations under the License.
00014 
00015 #include "osisoft-omf.h"
00016 #include "mbed.h"
00017 #include "https_request.h"
00018 #include "ntp-client/NTPClient.h"
00019 #include "config.egressSettings.h"
00020 #include "config.SSLCertificates.h"
00021 #include "config.producerToken.h"
00022 #include "config.OMFContainerAndLINKJSON.h"
00023 #include "config.OMFDynamicAndStaticTypesAndAssetJSON.h"
00024 
00025 // ---------------------------------------------------------------------------------------------------
00026 
00027 // The clock is set usign NTP; if that fails, the clock defaults to the below time
00028 const int DEFAULT_HARD_CODED_UTC_TIME = 1513175347;
00029 
00030 // ---------------------------------------------------------------------------------------------------
00031 
00032 // ************************************************************************
00033 // Helper function: prints out an HTTP response
00034 // ************************************************************************
00035  
00036 void OMFLib_dump_response(HttpResponse* res)
00037 {
00038     printf("\n\r----- HTTPS POST response -----\n\r");
00039     // Print the status code
00040     mbedtls_printf("Status: %d - %s\n\r", res->get_status_code(), res->get_status_message().c_str());
00041     // Print the headers
00042     mbedtls_printf("Response headers:\n\r");
00043     for (size_t ix = 0; ix < res->get_headers_length(); ix++) {
00044         mbedtls_printf("\t%s: %s\n\r", res->get_headers_fields()[ix]->c_str(), res->get_headers_values()[ix]->c_str());
00045     }
00046     // Print the body
00047     mbedtls_printf("Response body (%d bytes):\n\n%s", res->get_body_length(), res->get_body_as_string().c_str());
00048 }
00049 
00050 // ************************************************************************
00051 // Helper function that casts floats into strings
00052 // ************************************************************************
00053 
00054 string OMFLib_float_to_string(float f) {
00055     char buffer[20];
00056     int n = sprintf (buffer, "%f", f);
00057     // Return -1 if a parse failure ocurred
00058     if (string(buffer) == "NaN") {
00059         return string("-1");
00060     } else {
00061         return string(buffer);
00062     }
00063 }
00064 
00065 /* Deprecated after changes to TLS Socket 
00066 // ************************************************************************
00067 // Helper function that sends an actual web request
00068 // ************************************************************************
00069 
00070 void OMFLib_sendMessageToEndpoint(TLSSocket* socket, const char* action, const char* message_type, const char* body) {
00071     printf("\n\r----- HTTPS POST request -----\n\r");
00072     
00073     // Create the new request
00074     //HttpsRequest* post_req = new HttpsRequest(network, SSL_CA_PEM, HTTP_POST, TARGET_URL); // Old: doesn't re-use sockets
00075     HttpsRequest* post_req = new HttpsRequest(socket, HTTP_POST, TARGET_URL);
00076 
00077     // Turn on debugging - this hides TLS connection information (deprecated)
00078     //post_req->set_debug(true);
00079 
00080     // Add headers: content type and authentication
00081     post_req->set_header("Content-Type", "application/json");
00082 
00083     // Set OMF headers
00084     post_req->set_header("producertoken", PRODUCER_TOKEN);
00085     post_req->set_header("messagetype", message_type);
00086     post_req->set_header("action", action);
00087     post_req->set_header("messageformat", "JSON");
00088     post_req->set_header("omfversion", "1.0");
00089         
00090     // Send the body
00091     printf("Now sending request...");
00092     printf("\n\rOutgoing message headers:\n\tmessagetype: %s\n\taction: %s", message_type, action);
00093     printf("\n\rOutgoing message body:\n\t%s\n\r", body);
00094     HttpResponse* post_res = post_req->send(body, strlen(body));
00095 
00096     // Check the response for an error
00097     if (!post_res) {
00098         printf("HttpRequest failed (error code %d)\n\r", post_req->get_error());
00099         printf("Socket connection status after error: %d\n\r", socket->connected());
00100         //return 1;
00101     } else {
00102         // Print the response
00103         OMFLib_dump_response(post_res);
00104     }
00105 
00106     // Free up the request object
00107     delete post_req;
00108 }
00109 */
00110 
00111 // ************************************************************************
00112 // Helper function that sends an actual web request; does not reuse sockets
00113 // ************************************************************************
00114 
00115 #if ENABLE_PRINTOUTS == YES_ENABLE_PRINTOUTS
00116     void OMFLib_sendMessageToEndpoint_NoSocketReuse(NetworkInterface* network, const char* action, const char* message_type, const char* body) {
00117         
00118         printf("\n\r----- HTTPS POST request -----\n\r");
00119         
00120         // Create the new request
00121         HttpsRequest* post_req = new HttpsRequest(network, SSL_CA_PEM, HTTP_POST, TARGET_URL);
00122     
00123         // Turn on debugging - this hides TLS connection information (deprecated)
00124         //post_req->set_debug(true);
00125     
00126         // Add headers: content type 
00127         post_req->set_header("Content-Type", CONTENT_TYPE);
00128     
00129         // Set OMF headers
00130         post_req->set_header("producertoken", PRODUCER_TOKEN);
00131         post_req->set_header("messagetype", message_type);
00132         post_req->set_header("action", action);
00133         post_req->set_header("messageformat", OMF_MESSAGE_FORMAT);
00134         post_req->set_header("omfversion", OMF_VERSION);
00135             
00136         // Send the body
00137         printf("Now sending request... ");
00138         //printf("\n\rOutgoing message headers:\n\tmessagetype: %s\n\taction: %s", message_type, action);
00139         //printf("\n\rOutgoing message body:\n\t%s\n\r", body);
00140         HttpResponse* post_res = post_req->send(body, strlen(body));
00141         
00142         // Check the response for an error
00143         if (!post_res) {
00144             printf("HttpRequest failed (error code %d)\n\r", post_req->get_error());
00145             //return 1;
00146         } else {
00147             // Print the response
00148             printf("Success!\n\r");
00149             //OMFLib_dump_response(post_res);
00150         }
00151     
00152         // Free up the request object
00153         delete post_req;
00154     }
00155 #endif
00156 
00157 // Option if printouts should be hidden
00158 #if ENABLE_PRINTOUTS == DO_NOT_ENABLE_PRINTOUTS
00159     void OMFLib_sendMessageToEndpoint_NoSocketReuse(NetworkInterface* network, const char* action, const char* message_type, const char* body) {
00160 
00161         // Create the new request
00162         HttpsRequest* post_req = new HttpsRequest(network, SSL_CA_PEM, HTTP_POST, TARGET_URL);
00163     
00164         // Turn on debugging - this hides TLS connection information (deprecated)
00165         //post_req->set_debug(true);
00166     
00167         // Add headers: content type 
00168         post_req->set_header("Content-Type", CONTENT_TYPE);
00169     
00170         // Set OMF headers
00171         post_req->set_header("producertoken", PRODUCER_TOKEN);
00172         post_req->set_header("messagetype", message_type);
00173         post_req->set_header("action", action);
00174         post_req->set_header("messageformat", OMF_MESSAGE_FORMAT);
00175         post_req->set_header("omfversion", OMF_VERSION);
00176             
00177         // Send the body
00178         HttpResponse* post_res = post_req->send(body, strlen(body));
00179     
00180         // Free up the request object
00181         delete post_req;
00182     }
00183 #endif
00184 
00185 // ************************************************************************
00186 // Gets the current time in the appropriate OMF format
00187 // See https://os.mbed.com/blog/entry/103/
00188 // ************************************************************************
00189 const int TIMESTAMP_BUFFER_SIZE = 21;
00190 string OMFLib_getCurrentTimeString() {
00191     // Declar vars
00192     char timestampBuffer[TIMESTAMP_BUFFER_SIZE]; // The format is YYYY-MM-DDThh:mm:ssZ
00193     time_t now;
00194     //struct tm ts;
00195     
00196     // Set the "now" var to the current time
00197     time(&now);
00198     
00199     // Cast the current time into UTC seconds
00200     //ts = *localtime(&now);
00201     
00202     // Print out the time in seconds as a formatted string to the timestamp buffer
00203     //strftime(timestampBuffer, sizeof(timestampBuffer), "%Y-%m-%dT%H:%M:%SZ", &ts);
00204     //strftime(timestampBuffer, sizeof(timestampBuffer), "%Y-%m-%dT%H:%M:%SZ", &ts);
00205     strftime(timestampBuffer, TIMESTAMP_BUFFER_SIZE, "%Y-%m-%dT%H:%M:%SZ", localtime(&now));
00206     
00207     // Return the result
00208     return string(timestampBuffer);
00209 }
00210 
00211 // ************************************************************************
00212 // Sets the clock via NTP via the nwtwork; can point to a local or internet-based server
00213 // ************************************************************************
00214 
00215 void OMFLib_syncClockViaNTP(NetworkInterface* network) {
00216     // Hard-code a start time... see https://www.epochconverter.com/   
00217     set_time(DEFAULT_HARD_CODED_UTC_TIME);
00218     
00219     printf("\n\r----- Setting internal clock -----\n\r");
00220     // See https://github.com/ARMmbed/ntp-client-example/blob/master/main.cpp
00221     
00222     // Connect the ntp object to the network
00223     NTPClient ntp(network);
00224     
00225     // Set the ntp server to either an internet-based server OR to a local server
00226     ntp.set_server("2.pool.ntp.org", 123);
00227     
00228     // Get the timestamp via NTP
00229     time_t timestamp = ntp.get_timestamp();
00230     
00231     // Set the current timestamp to the NTP timestamp
00232     set_time(timestamp);
00233     
00234     // Print the result
00235     printf("Attempt done; clock set to UTC %s", ctime(&timestamp));
00236 }
00237 
00238 // ************************************************************************
00239 // Sends the dynamic types, static types, assets, and links messages
00240 // Uses the SEND_ASSETS_AND_LINKS MACRO found in config.egressSettings and
00241 // Uses the custom OMF JSON found in config.customOMFJSONStructures.h
00242 // ************************************************************************
00243 
00244 #if SEND_ASSETS_AND_LINKS == YES_SEND_ASSETS_AND_LINKS
00245     void OMFLib_sendInitialOMFMessages(NetworkInterface* __network_interface) {
00246         // Send the DYNAMIC types message, so that these types can be referenced in all later messages
00247         printf("\n\r!!!!!!!! Sending DYNAMIC Types message... !!!!!!!!\n\r");
00248         //OMFLib_sendMessageToEndpoint(socket, "create", "Type", dynamic_types_message_JSON.c_str());
00249         //OMFLib_sendMessageToEndpoint_NoSocketReuse(network, "create", "Type", DYNAMIC_TYPES_MESSAGE_JSON.c_str());
00250         OMFLib_sendMessageToEndpoint_NoSocketReuse(__network_interface, "create", "Type", DYNAMIC_TYPES_MESSAGE_JSON.c_str());
00251     
00252         // Send the container message, to instantiate this particular container; we can now directly start sending data to it using its Id
00253         printf("\n\r!!!!!!!! Sending Containers message... !!!!!!!!\n\r");
00254         //OMFLib_sendMessageToEndpoint(socket, "create", "Container", CONTAINERS_MESSAGE_JSON.c_str());  
00255         //OMFLib_sendMessageToEndpoint_NoSocketReuse(network, "create", "Container", CONTAINERS_MESSAGE_JSON.c_str());  
00256         OMFLib_sendMessageToEndpoint_NoSocketReuse(__network_interface, "create", "Container", CONTAINERS_MESSAGE_JSON.c_str()); 
00257         
00258         // ************************************************************************  
00259         // Send the STATIC types message, so that these types can be referenced in all later messages
00260         // ************************************************************************
00261     
00262         printf("\n\r!!!!!!!! Sending STATIC Types message... !!!!!!!!\n\r");
00263         //OMFLib_sendMessageToEndpoint(socket, "create", "Type", static_types_message_JSON.c_str()); 
00264         //OMFLib_sendMessageToEndpoint_NoSocketReuse(network, "create", "Type", STATIC_TYPES_MESSAGE_JSON.c_str());         
00265         OMFLib_sendMessageToEndpoint_NoSocketReuse(__network_interface, "create", "Type", STATIC_TYPES_MESSAGE_JSON.c_str());
00266     
00267         // ************************************************************************
00268         // Send the message to create the PI AF asset; it will not appear in PI AF, though, because it has not yet been positioned...
00269         // ************************************************************************
00270     
00271         printf("\n\r!!!!!!!! Sending Assets message... !!!!!!!!\n\r");
00272         //OMFLib_sendMessageToEndpoint(socket, "create", "Data", assets_message_JSON.c_str());
00273         //OMFLib_sendMessageToEndpoint_NoSocketReuse(network, "create", "Data", ASSETS_MESSAGE_JSON.c_str());  
00274         OMFLib_sendMessageToEndpoint_NoSocketReuse(__network_interface, "create", "Data", ASSETS_MESSAGE_JSON.c_str());
00275         
00276         // ************************************************************************
00277         // Send the message to link the PI AF asset
00278         // ************************************************************************
00279         
00280         printf("\n\r!!!!!!!! Sending Links message... !!!!!!!!\n\r");
00281         //OMFLib_sendMessageToEndpoint(socket, "create", "Data", LINKS_MESSAGE_JSON.c_str());
00282         //OMFLib_sendMessageToEndpoint_NoSocketReuse(network, "create", "Data", LINKS_MESSAGE_JSON.c_str());  
00283         OMFLib_sendMessageToEndpoint_NoSocketReuse(__network_interface, "create", "Data", LINKS_MESSAGE_JSON.c_str());
00284     }
00285 #endif
00286 
00287 // If assets and links should be skipped...
00288 #if SEND_ASSETS_AND_LINKS == DO_NOT_SEND_ASSETS_AND_LINKS
00289     void OMFLib_sendInitialOMFMessages(NetworkInterface* __network_interface) {
00290         // Send the DYNAMIC types message, so that these types can be referenced in all later messages
00291         printf("\n\r!!!!!!!! Sending DYNAMIC Types message... !!!!!!!!\n\r");
00292         //OMFLib_sendMessageToEndpoint(socket, "create", "Type", dynamic_types_message_JSON.c_str());
00293         //OMFLib_sendMessageToEndpoint_NoSocketReuse(network, "create", "Type", DYNAMIC_TYPES_MESSAGE_JSON.c_str());
00294         OMFLib_sendMessageToEndpoint_NoSocketReuse(__network_interface, "create", "Type", DYNAMIC_TYPES_MESSAGE_JSON.c_str());
00295     
00296         // Send the container message, to instantiate this particular container; we can now directly start sending data to it using its Id
00297         printf("\n\r!!!!!!!! Sending Containers message... !!!!!!!!\n\r");
00298         //OMFLib_sendMessageToEndpoint(socket, "create", "Container", CONTAINERS_MESSAGE_JSON.c_str());  
00299         //OMFLib_sendMessageToEndpoint_NoSocketReuse(network, "create", "Container", CONTAINERS_MESSAGE_JSON.c_str());  
00300         OMFLib_sendMessageToEndpoint_NoSocketReuse(__network_interface, "create", "Container", CONTAINERS_MESSAGE_JSON.c_str()); 
00301     }
00302 #endif