-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathAzure-Log-Analytics.ino
More file actions
224 lines (202 loc) · 6.99 KB
/
Copy pathAzure-Log-Analytics.ino
File metadata and controls
224 lines (202 loc) · 6.99 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
// Libraries
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <DHT.h> //Version 2.1.3
#include <sha256.h>
#include <rBase64.h>
#include <Time.h>
#include <TimeLib.h>
// WiFi settings
const char* ssid = "...";
const char* password = "...";
// Azure Log Analytics
const String CustomerId = "...";
const String SharedKey = "....==";
const String LogType = "IoT_Data";
const String AzureLASSLFingerPrint = "93 D9 CE 5E F8 75 E5 A4 83 E0 8A 20 F1 BB 75 5D F5 0B 31 97";
// DHT Sensor setting - from: https://learn.adafruit.com/esp8266-temperature-slash-humidity-webserver/code
#define DHTTYPE DHT22
#define DHTPIN 2
DHT dht(DHTPIN, DHTTYPE, 11);
float humidity, temp; // Values read from sensor
unsigned long previousMillis = 0; // will store last temp was read
const long interval = 2000; // interval at which to read sensor
// Main program settings
const int sleepTimeS = 20;
String RFC1123DateString = "";
void setup() {
// Init serial line
Serial.begin(115200);
Serial.println("ESP8266 starting");
// Connect to WiFi
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected");
// Print IP address
Serial.println(WiFi.localIP());
}
void loop() {
Serial.println();
// Read sensor
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval)
{
// save the last time you read the sensor
previousMillis = currentMillis;
humidity = dht.readHumidity(); // Read humidity (percent)
temp = dht.readTemperature(false); // Read temperature as Fahrenheit
//humidity=34; temp=21;
// Check if any reads failed and exit early (to try again).
if (isnan(humidity) || isnan(temp)) {
Serial.println("Failed to read from DHT sensor!");
} else
{
String PostData = "[{ \"SensorID\" : \"ESP8266-00000001\", \"SensorName\" : \"Basement\", \"DataType\" : \"Temperature\", \"DataValue\" : " + String(temp) + ", \"DataUnit\": \"Celcius\"},{ \"SensorID\" : \"ESP8266-00000001\", \"SensorName\" : \"Basement\", \"DataType\" : \"Humidity\", \"DataValue\" : " + String(humidity) + ", \"DataUnit\": \"RH\"}]";
Serial.println("Upload data:");
Serial.println(PostData);
// Send data to cloud
int postReturn = PostOMSData(CustomerId, SharedKey, PostData, LogType, "---", AzureLASSLFingerPrint);
Serial.print("Return code: ");
Serial.println(postReturn);
}
}
Serial.print("Waiting...");
delay(sleepTimeS * 1000);
Serial.println("Done.");
}
// Functions
String BuildSignature(String stringToHash, String sharedKey)
{
char str_array[sharedKey.length()-1];
sharedKey.toCharArray(str_array, sharedKey.length()-1);
size_t decLen=rbase64_dec_len(str_array,sharedKey.length()-1);
char output[decLen];
rbase64_decode(output, str_array, sharedKey.length()-1);
//Serial.print("COUNT: ");
//Serial.println(decLen);
byte keyBytes[decLen-1];
for (int i = 0; i < decLen-1; i++)
{
//Serial.println((int)output[i]);
keyBytes[i] = (int)output[i];
}
Sha256.init();
Sha256.initHmac(keyBytes, sizeof(keyBytes));
Sha256.print(stringToHash);
uint8_t *hash;
hash = Sha256.resultHmac();
rbase64.encode(hash, 32);
return rbase64.result();
}
int PostOMSData(String customerId, String sharedKey, String PostData, String logType, String timeGeneratedField, String fingerPrint)
{
RFC1123DateString = GetRFC1123DateString(RFC1123DateString);
String method = "POST";
String contentType = "application/json";
String resource = "/api/logs";
String rfc1123date = RFC1123DateString;
String xHeaders = "x-ms-date:" + rfc1123date;
String contentLength = (String) PostData.length();
String stringToHash = method + "\n" + contentLength + "\n" + contentType + "\n" + xHeaders + "\n" + resource;
String signature = "SharedKey " + customerId + ":" + BuildSignature(stringToHash, sharedKey);
Serial.println("Signature: "+signature);
String uri = "https://" + customerId + ".ods.opinsights.azure.com" + resource + "?api-version=2016-04-01";
Serial.println("Upload data to:");
Serial.println(uri);
Serial.println("Upload time:");
Serial.println(rfc1123date);
HTTPClient http;
http.begin(uri, fingerPrint);
http.addHeader("Authorization", signature);
http.addHeader("Content-Type", contentType);
http.addHeader("Log-Type", logType);
http.addHeader("x-ms-date", rfc1123date);
http.addHeader("time-generated-field", timeGeneratedField);
int returnCode = http.POST(PostData);
if (returnCode != 200)
{
Serial.println("RestPostData: Error sending data to Log Analytics: " + String(http.errorToString(returnCode).c_str()));
String payload = http.getString();
Serial.println(payload);
Serial.println(returnCode);
} else
{
http.end();
}
return returnCode;
}
void printHash(uint8_t* hash) {
int i;
for (i = 0; i < 32; i++) {
Serial.print("0123456789abcdef"[hash[i] >> 4]);
Serial.print("0123456789abcdef"[hash[i] & 0xf]);
}
Serial.println();
}
String GetRFC1123DateString(String LastDate)
{
const char* host = "time.nist.gov";
const int httpPort = 13;
String rfc1123date = LastDate;
tmElements_t tm;
time_t t;
String TimeDate = "";
WiFiClient client;
if (!client.connect(host, httpPort)) {
Serial.println("Error: GetRFC1123DateString - Connection failed!");
return rfc1123date;
}
client.print("HEAD / HTTP/1.1\r\nAccept: */*\r\nUser-Agent: Mozilla/4.0 (compatible; ESP8266 NodeMcu Lua;)\r\n\r\n");
char buffer[12];
String dateTime = "";
// Wait for client
unsigned long cMilliS = millis();
unsigned long lMilliS = cMilliS;
while (!client.available() and ((cMilliS - lMilliS) < 5000)) {
delay(80);
Serial.print("=");
cMilliS = millis();
}
while (client.available())
{
String line = client.readStringUntil('\r');
if (line.indexOf("Date") != -1)
{
Serial.print("=====>");
} else
{
TimeDate = line.substring(7);
char buf[3];
line.substring(13, 15).toCharArray(buf, sizeof(buf));
tm.Day = atoi(buf);
line.substring(10, 12).toCharArray(buf, sizeof(buf));
tm.Month = atoi(buf);
line.substring(7, 9).toCharArray(buf, sizeof(buf));
tm.Year = atoi(buf) + 2000 - 1970;
line.substring(16, 18).toCharArray(buf, sizeof(buf));
tm.Hour = atoi(buf);
line.substring(19, 21).toCharArray(buf, sizeof(buf));
tm.Minute = atoi(buf);
line.substring(22, 24).toCharArray(buf, sizeof(buf));
tm.Second = atoi(buf);
String timeUTC = line.substring(16, 24);
t = makeTime(tm);
rfc1123date = dayShortStr(weekday(t));
rfc1123date += ", ";
rfc1123date += line.substring(13, 15) + " ";
rfc1123date += monthShortStr(month(t));
rfc1123date += " 20" + line.substring(7, 9) + " ";
rfc1123date += timeUTC + " GMT";
if (rfc1123date == LastDate)
{
Serial.println("Error: GetRFC1123DateString - Unable to get date!");
}
}
}
client.stop();
return rfc1123date;
}