1+ #include < ESP8266WiFi.h>
2+ #include < WiFiClientSecure.h>
3+ #include < PubSubClient.h>
4+ #include < ArduinoJson.h> // https://github.com/bblanchon/ArduinoJson (use v6.xx)
5+ #include < time.h>
6+ #define emptyString String ()
7+
8+ #include " secrets.h"
9+
10+ const int MQTT_PORT = 8883 ;
11+ const char MQTT_SUB_TOPIC[] = " $aws/things/" THINGNAME " /shadow/update" ;
12+ const char MQTT_PUB_TOPIC[] = " $aws/things/" THINGNAME " /shadow/update" ;
13+
14+ uint8_t DST = 0 ;
15+ WiFiClientSecure net;
16+
17+ BearSSL::X509List cert (cacert);
18+ BearSSL::X509List client_crt (client_cert);
19+ BearSSL::PrivateKey key (privkey);
20+
21+ PubSubClient client (net);
22+
23+ unsigned long lastMillis = 0 ;
24+ time_t now;
25+ time_t nowish = 1510592825 ;
26+
27+ void NTPConnect (void )
28+ {
29+ Serial.print (" Setting time using SNTP" );
30+ configTime (TIME_ZONE * 3600 , DST * 3600 , " pool.ntp.org" , " time.nist.gov" );
31+ now = time (nullptr );
32+
33+ while (now < nowish) {
34+ delay (500 );
35+ Serial.print (" ." );
36+ now = time (nullptr );
37+ }
38+
39+ Serial.println (" done!" );
40+ struct tm timeinfo;
41+ gmtime_r (&now, &timeinfo);
42+
43+ Serial.print (" Current time: " );
44+ Serial.print (asctime (&timeinfo));
45+ }
46+
47+ void messageReceived (char *topic, byte *payload, unsigned int length)
48+ {
49+ Serial.print (" Received [" );
50+ Serial.print (topic);
51+ Serial.print (" ]: " );
52+
53+ for (int i = 0 ; i < length; i++) {
54+ Serial.print ((char )payload[i]);
55+ }
56+
57+ Serial.println ();
58+ }
59+
60+ void pubSubErr (int8_t MQTTErr)
61+ {
62+ if (MQTTErr == MQTT_CONNECTION_TIMEOUT)
63+ Serial.print (" Connection tiemout" );
64+ else if (MQTTErr == MQTT_CONNECTION_LOST)
65+ Serial.print (" Connection lost" );
66+ else if (MQTTErr == MQTT_CONNECT_FAILED)
67+ Serial.print (" Connect failed" );
68+ else if (MQTTErr == MQTT_DISCONNECTED)
69+ Serial.print (" Disconnected" );
70+ else if (MQTTErr == MQTT_CONNECTED)
71+ Serial.print (" Connected" );
72+ else if (MQTTErr == MQTT_CONNECT_BAD_PROTOCOL)
73+ Serial.print (" Connect bad protocol" );
74+ else if (MQTTErr == MQTT_CONNECT_BAD_CLIENT_ID)
75+ Serial.print (" Connect bad Client-ID" );
76+ else if (MQTTErr == MQTT_CONNECT_UNAVAILABLE)
77+ Serial.print (" Connect unavailable" );
78+ else if (MQTTErr == MQTT_CONNECT_BAD_CREDENTIALS)
79+ Serial.print (" Connect bad credentials" );
80+ else if (MQTTErr == MQTT_CONNECT_UNAUTHORIZED)
81+ Serial.print (" Connect unauthorized" );
82+ }
83+
84+ void connectToMqtt (bool nonBlocking = false )
85+ {
86+ Serial.print (" MQTT connecting " );
87+ while (!client.connected ()) {
88+ if (client.connect (THINGNAME)) {
89+ Serial.println (" connected!" );
90+ if (!client.subscribe (MQTT_SUB_TOPIC)) {
91+ pubSubErr (client.state ());
92+ }
93+ } else {
94+ Serial.print (" failed, reason -> " );
95+ pubSubErr (client.state ());
96+ if (!nonBlocking) {
97+ Serial.println (" < try again in 5 seconds" );
98+ delay (5000 );
99+ } else {
100+ Serial.println (" <" );
101+ }
102+ }
103+ if (nonBlocking) {
104+ break ;
105+ }
106+ }
107+ }
108+
109+ void connectToWiFi (String init_str)
110+ {
111+ if (init_str != emptyString) {
112+ Serial.print (init_str);
113+ }
114+ while (WiFi.status () != WL_CONNECTED) {
115+ Serial.print (" ." );
116+ delay (1000 );
117+ }
118+ if (init_str != emptyString) {
119+ Serial.println (" ok!" );
120+ }
121+ }
122+
123+ void checkWiFiThenMQTT (void )
124+ {
125+ connectToWiFi (" Checking WiFi" );
126+ connectToMqtt ();
127+ }
128+
129+ unsigned long previousMillis = 0 ;
130+ const long interval = 5000 ;
131+
132+ void checkWiFiThenMQTTNonBlocking (void )
133+ {
134+ connectToWiFi (emptyString);
135+ if (millis () - previousMillis >= interval && !client.connected ()) {
136+ previousMillis = millis ();
137+ connectToMqtt (true );
138+ }
139+ }
140+
141+ void checkWiFiThenReboot (void )
142+ {
143+ connectToWiFi (" Checking WiFi" );
144+ Serial.print (" Rebooting" );
145+ ESP.restart ();
146+ }
147+
148+ void sendData (void )
149+ {
150+ DynamicJsonDocument jsonBuffer (JSON_OBJECT_SIZE (3 ) + 100 );
151+
152+ JsonObject root = jsonBuffer.to <JsonObject>();
153+ JsonObject state = root.createNestedObject (" state" );
154+ JsonObject state_reported = state.createNestedObject (" reported" );
155+
156+ state_reported[" value" ] = random (100 );
157+
158+ Serial.printf (" Sending [%s]: " , MQTT_PUB_TOPIC);
159+ serializeJson (root, Serial);
160+
161+ Serial.println ();
162+
163+ char shadow[measureJson (root) + 1 ];
164+
165+ serializeJson (root, shadow, sizeof (shadow));
166+ if (!client.publish (MQTT_PUB_TOPIC, shadow, false )) {
167+ pubSubErr (client.state ());
168+ }
169+ }
170+
171+ void setup ()
172+ {
173+ Serial.begin (115200 );
174+ delay (5000 );
175+ Serial.println ();
176+ Serial.println ();
177+
178+ WiFi.hostname (THINGNAME);
179+ WiFi.mode (WIFI_STA);
180+ WiFi.begin (ssid, pass);
181+
182+ connectToWiFi (String (" Attempting to connect to SSID: " ) + String (ssid));
183+
184+ NTPConnect ();
185+
186+ net.setTrustAnchors (&cert);
187+ net.setClientRSACert (&client_crt, &key);
188+
189+ client.setServer (MQTT_HOST, MQTT_PORT);
190+ client.setCallback (messageReceived);
191+
192+ connectToMqtt ();
193+ }
194+
195+ void loop ()
196+ {
197+ now = time (nullptr );
198+ if (!client.connected ()) {
199+ checkWiFiThenMQTT ();
200+ // checkWiFiThenMQTTNonBlocking();
201+ // checkWiFiThenReboot();
202+ } else {
203+ client.loop ();
204+ if (millis () - lastMillis > 5000 ) {
205+ lastMillis = millis ();
206+ sendData ();
207+ }
208+ }
209+ }
0 commit comments