Separate library that holds helper functions for the main OMF code.
osisoft-omf.cpp
- Committer:
- danielelopez
- Date:
- 2018-06-25
- Revision:
- 18:c6c9cce5d990
- Parent:
- 17:cc05a00e6ee6
- Child:
- 19:9b357e31f61d
File content as of revision 18:c6c9cce5d990:
//Copyright 2018 OSIsoft, LLC // //Licensed under the Apache License, Version 2.0 (the "License"); //you may not use this file except in compliance with the License. //You may obtain a copy of the License at // //<http://www.apache.org/licenses/LICENSE-2.0> // //Unless required by applicable law or agreed to in writing, software //distributed under the License is distributed on an "AS IS" BASIS, //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. //See the License for the specific language governing permissions and //limitations under the License. #include "osisoft-omf.h" #include "mbed.h" #include "https_request.h" #include "ntp-client/NTPClient.h" #include "config.egressSettings.h" #include "config.SSLCertificates.h" #include "config.producerToken.h" #include "config.OMFContainerAndLINKJSON.h" #include "config.OMFDynamicAndStaticTypesAndAssetJSON.h" // --------------------------------------------------------------------------------------------------- // The clock is set usign NTP; if that fails, the clock defaults to the below time const int DEFAULT_HARD_CODED_UTC_TIME = 1513175347; // --------------------------------------------------------------------------------------------------- // ************************************************************************ // Helper function: prints out an HTTP response // ************************************************************************ void OMFLib_dump_response(HttpResponse* res) { printf("\n\r----- HTTPS POST response -----\n\r"); // Print the status code mbedtls_printf("Status: %d - %s\n\r", res->get_status_code(), res->get_status_message().c_str()); // Print the headers mbedtls_printf("Response headers:\n\r"); for (size_t ix = 0; ix < res->get_headers_length(); ix++) { mbedtls_printf("\t%s: %s\n\r", res->get_headers_fields()[ix]->c_str(), res->get_headers_values()[ix]->c_str()); } // Print the body mbedtls_printf("Response body (%d bytes):\n\n%s", res->get_body_length(), res->get_body_as_string().c_str()); } // ************************************************************************ // Helper function that casts floats into strings // ************************************************************************ string OMFLib_float_to_string(float f) { char buffer[20]; int n = sprintf (buffer, "%f", f); // Return -1 if a parse failure ocurred if (string(buffer) == "NaN") { return string("-1"); } else { return string(buffer); } } // ************************************************************************ // Helper function that sends an actual web request // ************************************************************************ void OMFLib_sendMessageToEndpoint(TLSSocket* socket, const char* action, const char* message_type, const char* body) { printf("\n\r----- HTTPS POST request -----\n\r"); // Create the new request //HttpsRequest* post_req = new HttpsRequest(network, SSL_CA_PEM, HTTP_POST, TARGET_URL); // Old: doesn't re-use sockets HttpsRequest* post_req = new HttpsRequest(socket, HTTP_POST, TARGET_URL); // Turn on debugging - this hides TLS connection information post_req->set_debug(true); // Add headers: content type and authentication post_req->set_header("Content-Type", "application/json"); // Set OMF headers post_req->set_header("producertoken", PRODUCER_TOKEN); post_req->set_header("messagetype", message_type); post_req->set_header("action", action); post_req->set_header("messageformat", "JSON"); post_req->set_header("omfversion", "1.0"); // Send the body printf("Now sending request..."); printf("\n\rOutgoing message headers:\n\tmessagetype: %s\n\taction: %s", message_type, action); printf("\n\rOutgoing message body:\n\t%s\n\r", body); HttpResponse* post_res = post_req->send(body, strlen(body)); // Check the response for an error if (!post_res) { printf("HttpRequest failed (error code %d)\n\r", post_req->get_error()); printf("Socket connection status after error: %d\n\r", socket->connected()); //return 1; } else { // Print the response OMFLib_dump_response(post_res); } // Free up the request object delete post_req; } // ************************************************************************ // Helper function that sends an actual web request; does not reuse sockets // ************************************************************************ #if ENABLE_PRINTOUTS == YES_ENABLE_PRINTOUTS void OMFLib_sendMessageToEndpoint_NoSocketReuse(NetworkInterface* network, const char* action, const char* message_type, const char* body) { printf("\n\r----- HTTPS POST request -----\n\r"); // Create the new request HttpsRequest* post_req = new HttpsRequest(network, SSL_CA_PEM, HTTP_POST, TARGET_URL); // Turn on debugging - this hides TLS connection information //post_req->set_debug(true); // Add headers: content type post_req->set_header("Content-Type", CONTENT_TYPE); // Set OMF headers post_req->set_header("producertoken", PRODUCER_TOKEN); post_req->set_header("messagetype", message_type); post_req->set_header("action", action); post_req->set_header("messageformat", OMF_MESSAGE_FORMAT); post_req->set_header("omfversion", OMF_VERSION); // Send the body printf("Now sending request... "); //printf("\n\rOutgoing message headers:\n\tmessagetype: %s\n\taction: %s", message_type, action); //printf("\n\rOutgoing message body:\n\t%s\n\r", body); HttpResponse* post_res = post_req->send(body, strlen(body)); // Check the response for an error if (!post_res) { printf("HttpRequest failed (error code %d)\n\r", post_req->get_error()); //return 1; } else { // Print the response printf("Success!\n\r"); //OMFLib_dump_response(post_res); } // Free up the request object delete post_req; } #endif // Option if printouts should be hidden #if ENABLE_PRINTOUTS == DO_NOT_ENABLE_PRINTOUTS void OMFLib_sendMessageToEndpoint_NoSocketReuse(NetworkInterface* network, const char* action, const char* message_type, const char* body) { // Create the new request HttpsRequest* post_req = new HttpsRequest(network, SSL_CA_PEM, HTTP_POST, TARGET_URL); // Turn on debugging - this hides TLS connection information //post_req->set_debug(true); // Add headers: content type post_req->set_header("Content-Type", CONTENT_TYPE); // Set OMF headers post_req->set_header("producertoken", PRODUCER_TOKEN); post_req->set_header("messagetype", message_type); post_req->set_header("action", action); post_req->set_header("messageformat", OMF_MESSAGE_FORMAT); post_req->set_header("omfversion", OMF_VERSION); // Send the body HttpResponse* post_res = post_req->send(body, strlen(body)); // Free up the request object delete post_req; } #endif // ************************************************************************ // Gets the current time in the appropriate OMF format // See https://os.mbed.com/blog/entry/103/ // ************************************************************************ const int TIMESTAMP_BUFFER_SIZE = 21; string OMFLib_getCurrentTimeString() { // Declar vars char timestampBuffer[TIMESTAMP_BUFFER_SIZE]; // The format is YYYY-MM-DDThh:mm:ssZ time_t now; //struct tm ts; // Set the "now" var to the current time time(&now); // Cast the current time into UTC seconds //ts = *localtime(&now); // Print out the time in seconds as a formatted string to the timestamp buffer //strftime(timestampBuffer, sizeof(timestampBuffer), "%Y-%m-%dT%H:%M:%SZ", &ts); //strftime(timestampBuffer, sizeof(timestampBuffer), "%Y-%m-%dT%H:%M:%SZ", &ts); strftime(timestampBuffer, TIMESTAMP_BUFFER_SIZE, "%Y-%m-%dT%H:%M:%SZ", localtime(&now)); // Return the result return string(timestampBuffer); } // ************************************************************************ // Sets the clock via NTP via the nwtwork; can point to a local or internet-based server // ************************************************************************ void OMFLib_syncClockViaNTP(NetworkInterface* network) { // Hard-code a start time... see https://www.epochconverter.com/ set_time(DEFAULT_HARD_CODED_UTC_TIME); printf("\n\r----- Setting internal clock -----\n\r"); // See https://github.com/ARMmbed/ntp-client-example/blob/master/main.cpp // Connect the ntp object to the network NTPClient ntp(network); // Set the ntp server to either an internet-based server OR to a local server ntp.set_server("2.pool.ntp.org", 123); // Get the timestamp via NTP time_t timestamp = ntp.get_timestamp(); // Set the current timestamp to the NTP timestamp set_time(timestamp); // Print the result printf("Attempt done; clock set to UTC %s", ctime(×tamp)); } // ************************************************************************ // Sends the dynamic types, static types, assets, and links messages // Uses the SEND_ASSETS_AND_LINKS MACRO found in config.egressSettings and // Uses the custom OMF JSON found in config.customOMFJSONStructures.h // ************************************************************************ #if SEND_ASSETS_AND_LINKS == YES_SEND_ASSETS_AND_LINKS void OMFLib_sendInitialOMFMessages(NetworkInterface* __network_interface) { // Send the DYNAMIC types message, so that these types can be referenced in all later messages printf("\n\r!!!!!!!! Sending DYNAMIC Types message... !!!!!!!!\n\r"); //OMFLib_sendMessageToEndpoint(socket, "create", "Type", dynamic_types_message_JSON.c_str()); //OMFLib_sendMessageToEndpoint_NoSocketReuse(network, "create", "Type", DYNAMIC_TYPES_MESSAGE_JSON.c_str()); OMFLib_sendMessageToEndpoint_NoSocketReuse(__network_interface, "create", "Type", DYNAMIC_TYPES_MESSAGE_JSON.c_str()); // Send the container message, to instantiate this particular container; we can now directly start sending data to it using its Id printf("\n\r!!!!!!!! Sending Containers message... !!!!!!!!\n\r"); //OMFLib_sendMessageToEndpoint(socket, "create", "Container", CONTAINERS_MESSAGE_JSON.c_str()); //OMFLib_sendMessageToEndpoint_NoSocketReuse(network, "create", "Container", CONTAINERS_MESSAGE_JSON.c_str()); OMFLib_sendMessageToEndpoint_NoSocketReuse(__network_interface, "create", "Container", CONTAINERS_MESSAGE_JSON.c_str()); // ************************************************************************ // Send the STATIC types message, so that these types can be referenced in all later messages // ************************************************************************ printf("\n\r!!!!!!!! Sending STATIC Types message... !!!!!!!!\n\r"); //OMFLib_sendMessageToEndpoint(socket, "create", "Type", static_types_message_JSON.c_str()); //OMFLib_sendMessageToEndpoint_NoSocketReuse(network, "create", "Type", STATIC_TYPES_MESSAGE_JSON.c_str()); OMFLib_sendMessageToEndpoint_NoSocketReuse(__network_interface, "create", "Type", STATIC_TYPES_MESSAGE_JSON.c_str()); // ************************************************************************ // Send the message to create the PI AF asset; it will not appear in PI AF, though, because it has not yet been positioned... // ************************************************************************ printf("\n\r!!!!!!!! Sending Assets message... !!!!!!!!\n\r"); //OMFLib_sendMessageToEndpoint(socket, "create", "Data", assets_message_JSON.c_str()); //OMFLib_sendMessageToEndpoint_NoSocketReuse(network, "create", "Data", ASSETS_MESSAGE_JSON.c_str()); OMFLib_sendMessageToEndpoint_NoSocketReuse(__network_interface, "create", "Data", ASSETS_MESSAGE_JSON.c_str()); // ************************************************************************ // Send the message to link the PI AF asset // ************************************************************************ printf("\n\r!!!!!!!! Sending Links message... !!!!!!!!\n\r"); //OMFLib_sendMessageToEndpoint(socket, "create", "Data", LINKS_MESSAGE_JSON.c_str()); //OMFLib_sendMessageToEndpoint_NoSocketReuse(network, "create", "Data", LINKS_MESSAGE_JSON.c_str()); OMFLib_sendMessageToEndpoint_NoSocketReuse(__network_interface, "create", "Data", LINKS_MESSAGE_JSON.c_str()); } #endif // If assets and links should be skipped... #if SEND_ASSETS_AND_LINKS == DO_NOT_SEND_ASSETS_AND_LINKS void OMFLib_sendInitialOMFMessages(NetworkInterface* __network_interface) { // Send the DYNAMIC types message, so that these types can be referenced in all later messages printf("\n\r!!!!!!!! Sending DYNAMIC Types message... !!!!!!!!\n\r"); //OMFLib_sendMessageToEndpoint(socket, "create", "Type", dynamic_types_message_JSON.c_str()); //OMFLib_sendMessageToEndpoint_NoSocketReuse(network, "create", "Type", DYNAMIC_TYPES_MESSAGE_JSON.c_str()); OMFLib_sendMessageToEndpoint_NoSocketReuse(__network_interface, "create", "Type", DYNAMIC_TYPES_MESSAGE_JSON.c_str()); // Send the container message, to instantiate this particular container; we can now directly start sending data to it using its Id printf("\n\r!!!!!!!! Sending Containers message... !!!!!!!!\n\r"); //OMFLib_sendMessageToEndpoint(socket, "create", "Container", CONTAINERS_MESSAGE_JSON.c_str()); //OMFLib_sendMessageToEndpoint_NoSocketReuse(network, "create", "Container", CONTAINERS_MESSAGE_JSON.c_str()); OMFLib_sendMessageToEndpoint_NoSocketReuse(__network_interface, "create", "Container", CONTAINERS_MESSAGE_JSON.c_str()); } #endif