Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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(×tamp)); 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
Generated on Wed Jul 13 2022 06:27:45 by
