1+ #include < time.h>
2+ #include < WiFi.h>
3+ #include < BytebeamArduino.h>
4+ #include " arduino_secrets.h"
5+
6+ // on board led pin number
7+ #define BOARD_LED 2
8+
9+ // led state variable
10+ int ledState = 0 ;
11+
12+ // wifi credentials
13+ const char * WIFI_SSID = SECRET_SSID;
14+ const char * WIFI_PASSWORD = SECRET_PASS;
15+
16+ // sntp credentials
17+ const long gmtOffset_sec = 19800 ; // GMT + 5:30h
18+ const int daylightOffset_sec = 0 ;
19+ const char * ntpServer = " pool.ntp.org" ;
20+
21+ // Replace this with your device config json in the same format
22+ char deviceConfigData[] = R"(
23+ {
24+ "project_id": "demo",
25+ "broker": "cloud.bytebeam.io",
26+ "port": 8883,
27+ "device_id": "1",
28+ "authentication": {
29+ "ca_certificate": "-----BEGIN CERTIFICATE-----\nMIIFrDCCA5SgAwIBAgICBMwDQYJAwdzEOMAwGA1UBhMFSW5k\naWExETAPBgNVBAgTCEthcm5hdGFrMRIwEAYcmUxFzAVBgNV\nBAkTDlN1YmJpYWggR2FyZGVuMQ8wDQYDVQQREwY1NjAwMTExFDASBgNVBAoTC0J5\ndGViZWFtLmlvMB4XDTIxMDkwMjExMDYyM1oXDTMxMDkwMjExMDYyM1owdzEOMAwG\nA1UEBhMFSW5kaWExETAPBgNVBAgTCEthcm5hdGFrMRIwEAYDVQQHEwlCYW5nYWxv\ncmUxFzAVBgNVBAkTDlN1YmJpYWggR2FyZGVuMQ8wDQYDVQQREwY1NjAwMTExFDAS\nBgNVBAoTC0J5dGViZWFtLmlvMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC\nAgEAr/bnOa/8AUGZmd/s+7rejuROgeLqqU9X15KKfKOBqcoMyXsSO65UEwpzadpw\nMl7GDCdHqFTymqdnAnbhgaT1PoIFhOG64y7UiNgiWmbh0XJj8G6oLrW9rQ1gug1Q\n/D7x2fUnza71aixiwEL+KsIFYIdDuzmoRD3rSer/bKOcGGs0WfB54KqIVVZ1DwsU\nk1wx5ExsKo7gAdXMAbdHRI2Szmn5MsZwGL6V0LfsKLE8ms2qlZe50oo2woLNN6XP\nRfRL4bwwkdsCqXWkkt4eUSNDq9hJsuINHdhO3GUieLsKLJGWJ0lq6si74t75rIKb\nvvsFEQ9mnAVS+iuUUsSjHPJIMnn/J64Nmgl/R/8FP5TUgUrHvHXKQkJ9h/a7+3tS\nlV2KMsFksXaFrGEByGIJ7yR4qu9hx5MXf8pf8EGEwOW/H3CdWcC2MvJ11PVpceUJ\neDVwE7B4gPM9Kx02RNwvUMH2FmYqkXX2DrrHQGQuq+6VRoN3rEdmGPqnONJEPeOw\nZzcGDVXKWZtd7UCbcZKdn0RYmVtI/OB5OW8IRoXFYgGB3IWP796dsXIwbJSqRb9m\nylICGOceQy3VR+8+BHkQLj5/ZKTe+AA3Ktk9UADvxRiWKGcejSA/LvyT8qzz0dqn\nGtcHYJuhJ/XpkHtB0PykB5WtxFjx3G/osbZfrNflcQZ9h1MCAwEAAaNCMEAwDgYD\nVR0PAQH/BAQDAgKEMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFKl/MTbLrZ0g\nurneOmAfBHO+LHz+MA0GCSqGSIb3DQEBCwUAA4ICAQAlus/uKic5sgo1d2hBJ0Ak\ns1XJsA2jz+OEdshQHmCCmzFir3IRSuVRmDBaBGlJDHCELqYxKn6dl/sKGwoqoAQ5\nOeR2sey3Nmdyw2k2JTDx58HnApZKAVir7BDxbIbbHmfhJk4ljeUBbertNXWbRHVr\ncs4XBNwXvX+noZjQzmXXK89YBsV2DCrGRAUeZ4hQEqV7XC0VKmlzEmfkr1nibDr5\nqwbI+7QWIAnkHggYi27lL2UTH7TvkwYC4TyDaoQ2ZRpG\nHY+mxXLdftoMv/ZvmyjOPYeTRQbfPqoRqcM6XOPXwSw9B6YddwmnkI7ohNOvAVfD\nwGptUc5OodgFQc3waRljX1q2lawZCTh58IUf32CRtOEL2RIz4VpUrNF/0E2vts1f\npO7V1vY2Qin998Nwqkxdsll0GLtEEE9hUyvk1F8U+fgjJ3Rjn4BxnCN4oCrdJOMa\nJCaysaHV7EEIMqrYP4jH6RzQzOXLd0m9NaL8A/Y9z2a96fwpZZU/fEEOH71t3Eo3\nV/CKlysiALMtsHfZDwHNpa6g0NQNGN5IRl/w1TS1izzjzgWhR6r8wX8OPLRzhNRz\n2HDbTXGYsem0ihC0B8uzujOhTHcBwsfxZUMpGjg8iycJlfpPDWBdw8qrGu8LeNux\na0cIevjvYAtVysoXInV0kg==\n-----END CERTIFICATE-----\n",
30+ "device_certificate": "-----BEGIN CERTIFICATE-----\nMIIEcjCCAlqgAwIBAgICB+MwhMFSW5k\naWExETAPBgNVBAgTCEthcm5hdGFrMRIwEAYDVQQHEwlCN1YmJpYWggR2FyZGVuMQ8wDQYDVQQREwY1NjAwMTExFDASBgNVBAoTC0J5\ndGViZWFtLmlvMB4XDTIyMTEwMzA3NDcwMloXDTMyMTEKTEbMBkG\nA1UEChMSZXNwYnl0ZWJlYW1zZGt0ZXN0MQowCAYDVQQDEwExMIIBIjANBgkqhkiG\n9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzsm8CF8fKSzWFKZeO52RJRGER4z7sYrgTb9x\noIeljE8kmhR+EW217sxUyUn+rmJSCxRz6jtspKv37POPaQilmwtriVq8L46YCrXa\nbI9manlqw0WqAfaWAlFXzM13CuXeGZKhuAK3INs15jqP0s+oWFvww8+hww540I+s\nn6j5yEUnWKSIgoYEc82cwvj0qOvaxYxjUTXgV2IDLSXdFJbZq4k9LDbzPZdDe0aY\n4X9UpdrjS5cRWT3Ok4VwWpMRwOT654CTwE8WUja/pHTRFbMYkqd1jrD2Joqtm+u9\nplTq7I9/fDnkRqPjueDQ04LKTbUC2UsRKw1VmHPndw22+mDPUwIDAQABo1YwVDAO\nBgNVHQ8BAf8EBAMCBaAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwHwYDVR0jBBgwFoAU\nqX8xNsutnSC6ud46YB8Ec74sfP4wDAYDVR0RBAUwA4IBMTANBgkqhkiG9w0BAQsF\nAAOCAgEAcj5Ytt47AdmsXBsv/K7YkUvkNwV64luBMQtqmTKRDWnIQLaFzPjdpieu\n81ktFKklKw6pReWdUPSBy6hKq3zzGvSsShBSghbOAJvlPkK6jpLy5TzZdIj8ug7g\nMCzZvqdmznekSg4elGHJIYUfHD6ZUJaEkkGD1yQpxOIVCnodhN2246SXJK23itmz\nB5y1AHU5zydN7Ys0oY1l8RCc5Iz24IcQAi//2pIPe9ORks3QBBi+qY9m+emHCqgb\n48hNe5v7X+yF4VITlWs3Mfk0gSgbDQ4OwVf/8/D7o0hQ8EU5bzXNvf49Kd2mWTii\nQdQDdNLxZsdgWNwYdqrQhA0qN02yJxkhNm5GXmP75zmg0bPe4I+pNwuy+B32wFZn\nNcZrh4HZzS1cAyyyr3E59zsPjqcohaUcBpe6oUoQ8z1V7K9FR31TnFfvjg9mbDnX\nv2+PXsp0m7f4e1QfepZxUwyjemxOe/b+IEc7PckIrkPy46JaIvi9ONrTR8Y5wDir\nbGuzpmiyMFlyzK4ULh7kt7MU/jU/ulnqDU8JvAnhhxK3kgV4vv8LSYJSEYYP9i1S\nj/EPPQBANdtr4B2pcV1ig13dinq7rir6Q/pnkKrAFOfZcvOWW2BvPOC2dcnCYJpB\n1R5QJGXqna8Uh+ZwThs0K/Nd9dml1w/Rug8hx0VHoIe6AjXEepQ=\n-----END CERTIFICATE-----\n",
31+ "device_private_key": "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEAzsm8CF8fKSzWFKZeO52RJRmhR+\nEW217sxUyUn+rmJSCxRz6jtspKv37POPaQilmwtriVq8L46YCrXabI9manlqw0Wq\nAfaWAlFXzM13CuXeGZKhuAK3INs15jqP0s+oWFvww8+hww540I+sn6j5yEUnWKSI\ngoYEc82cwvj0qOvaxYxjUTXgV2IDLSXdFJbZq4k9LDbzPZdDe0aY4X9UpdrjS5cR\nWT3Ok4VwWpMRwOT654CTwE8WUja/pHTRFbMYkqd1jrD2Joqtm+u9plTq7I9/fDnk\nRqPjueDQ04LKTbUC2UsRKw1VmHPndw22+mDPUwIDAQABAoIBAHv3A/ogzBVrA4ut\nkKA8fV6zeZFLOzfcAUuakQujReMvLsoPruPT2VUmuU1SRpNT7csmn7azmRW+4gny\nmO5meKDR382fz2DTIuKI0kByVvtNfmtBwAEdSiBpkzD7m3m1A8hg1wHw3sebolw6\njy3Zvxn5RASe3GKKsnKVLu8n5VXgyytn2I6sYOmKoLv3N9V3tziHL3Gl2AfWAd5P\nJHJdxZ50hhjzUnI0MmvUU6M9G26xagxNNibzOWv3BEuBRw5fuVpt/QoBouFhcKF7\nEdCFpiZ8LJFpux6FyLDOOAa7mj+Y6yK1qKsJbFGG8AnhPTO/bAc1m7yQcJygH9cl\nretVDcECgYEA4z+NkjqIPRiAvOsmJD6KfMeABkZc4JmART+KtrpoJmPWc2WDxu8M\ngP1eqmh/aGGORY8hcFyl+SIf5JvP13Dd/47tSK4vhyEGnnqRt+wjjuzci0rDvFdH\ntaUbjlb4kKStssQPTTmG726Zd1f32eKzBnCY8YqWdMMM1HXak20rPo8CgYEA6PN8\nYIcIrRkFzyvam8m5pCeoHylBgSNjN2j8dGC8b6SGMG6y4+rUiuxfhC/Oq7UtOvf+\njYQQgeMjB22dhcvJa6rjuuKXXpbcgNnzcemnySohUr7Nm1bXHwRfoqMAmeh3pkcL\nL+K4Mf6Gd1i2hiYd4Dd59m5/p3W+QUyKa4iaRP0CgYAf2/UZHyOijSDfW4hJZIs9\n2ypTtuGmi160Vqg33gJj/3M9UmobJcB3BQ6UjXnvRF4R2nMxsYuDVglqn32QEr7M\n6VjS67i2FSc8aKqtQmnpy8NPs/elHAdtq+wlFIRcovnHKj2K8hm8z6CsXqTc4y9+\nI6MNmgRl8kKGNs+iA5ggeQKBgBKLN25zsWQeJtE8G3XlVArWQVLhtN4z0/UYPWiC\nPt3gSfJXDZSJIAxDDsN2DsyqaoRUM4ZOagX878/qkOySsWEJxIEfAo+8EKeNMgzy\nXbHs0aRFnhZsjklgzsAim6ykzcmFxEU2lhUcvtWHUVhSdnRf1iyg1Taeb9vA3Q/8\nWtN9AoGBAN+rik+pvcdPAexngqmsUgoW8Abvv7dyBmt99KfnyRDfbt6EM68CZI90\naOlNE9P7XZyOyfQdzOlJWv8B78dwrbwMiwkhGtMjEzdW\nKFI0T+ZOXN99GcKLHeg5GfGqHcHlEhXP9BtRyTJVz914alvOIaiY\n-----END RSA PRIVATE KEY-----\n"
32+ }
33+ }
34+ )" ;
35+
36+ // function to setup the wifi with predefined credentials
37+ void setupWifi () {
38+ // set the wifi to station mode to connect to a access point
39+ WiFi.mode (WIFI_STA);
40+ WiFi.begin (WIFI_SSID , WIFI_PASSWORD);
41+
42+ Serial.println ();
43+ Serial.print (" Connecting to " + String (WIFI_SSID));
44+
45+ // wait till chip is being connected to wifi (Blocking Mode)
46+ while (WiFi.status () != WL_CONNECTED) {
47+ Serial.print (" ." );
48+ delay (250 );
49+ }
50+
51+ // now it is connected to the access point just print the ip assigned to chip
52+ Serial.println ();
53+ Serial.print (" Connected to " + String (WIFI_SSID) + " , Got IP address : " );
54+ Serial.println (WiFi.localIP ());
55+ }
56+
57+ // function to sync time from ntp server with predefined credentials
58+ void syncTimeFromNtp () {
59+ // sync the time from ntp server
60+ configTime (gmtOffset_sec, daylightOffset_sec, ntpServer);
61+
62+ struct tm timeinfo;
63+
64+ // get the current time
65+ if (!getLocalTime (&timeinfo)) {
66+ Serial.println (" Failed to obtain time" );
67+ return ;
68+ }
69+
70+ // log the time info to serial :)
71+ Serial.println (&timeinfo, " %A, %B %d %Y %H:%M:%S" );
72+ Serial.println ();
73+ }
74+
75+ // function to setup the predefined led
76+ void setupLED () {
77+ pinMode (BOARD_LED, OUTPUT);
78+ digitalWrite (BOARD_LED, ledState);
79+ }
80+
81+ // function to toggle the predefined led
82+ void toggleLED () {
83+ ledState = !ledState;
84+ digitalWrite (BOARD_LED, ledState);
85+ }
86+
87+ // function to get the time
88+ unsigned long long getEpochMillis () {
89+ time_t now;
90+ struct tm timeinfo;
91+
92+ // get the current time i.e make sure the device is in sync with the ntp server
93+ if (!getLocalTime (&timeinfo)) {
94+ Serial.println (" failed to obtain time" );
95+ return 0 ;
96+ }
97+
98+ // get the epoch time
99+ time (&now);
100+
101+ // generate the epoch millis
102+ unsigned long long timeMillis = ((unsigned long long )now * 1000 ) + (millis () % 1000 );
103+
104+ return timeMillis;
105+ }
106+
107+ // function to publish payload to device shadow
108+ bool publishToDeviceShadow () {
109+ static int sequence = 0 ;
110+ unsigned long long milliseconds = 0 ;
111+ char ledStatus[200 ] = " " ;
112+ char deviceShadowStream[] = " device_shadow" ;
113+
114+ const char * payload = " " ;
115+ String deviceShadowStr = " " ;
116+ StaticJsonDocument<1024 > doc;
117+
118+ // get the current epoch millis
119+ milliseconds = getEpochMillis ();
120+
121+ // make sure you got the millis
122+ if (milliseconds == 0 ) {
123+ Serial.println (" failed to get epoch millis" );
124+ return false ;
125+ }
126+
127+ // increment the sequence counter
128+ sequence++;
129+
130+ // generate the led status message string
131+ sprintf (ledStatus, " LED is %s !" , ledState == true ? " ON" : " OFF" );
132+
133+ JsonArray deviceShadowJsonArray = doc.to <JsonArray>();
134+ JsonObject deviceShadowJsonObj_1 = deviceShadowJsonArray.createNestedObject ();
135+
136+ deviceShadowJsonObj_1[" timestamp" ] = milliseconds;
137+ deviceShadowJsonObj_1[" sequence" ] = sequence;
138+ deviceShadowJsonObj_1[" Status" ] = ledStatus;
139+
140+ serializeJson (deviceShadowJsonArray, deviceShadowStr);
141+ payload = deviceShadowStr.c_str ();
142+
143+ Serial.printf (" publishing %s to %s\n " , payload, deviceShadowStream);
144+
145+ return Bytebeam.publishToStream (deviceShadowStream, payload);
146+ }
147+
148+ // handler for ToggleLED action
149+ int ToggleLED_Hanlder (char * args, char * actionId) {
150+ Serial.println (" ToggleLED Action Received !" );
151+ Serial.printf (" <--- args : %s, actionId : %s --->\n " , args, actionId);
152+
153+ // toggle the led
154+ toggleLED ();
155+
156+ // publish led state to device shadow
157+ if (!publishToDeviceShadow ()) {
158+ // publish action failed status
159+ if (!Bytebeam.publishActionFailed (actionId, " Publish led state to device shadow Failed" )) {
160+ Serial.println (" Failed to publish action failed response for Toggle LED action" );
161+ }
162+
163+ Serial.println (" Failed to publish led state to device shadow" );
164+ return -1 ;
165+ }
166+
167+ // publish action completed status
168+ if (!Bytebeam.publishActionCompleted (actionId)) {
169+ Serial.println (" Failed to publish action completed response for Toggle LED action" );
170+ return -1 ;
171+ }
172+
173+ return 0 ;
174+ }
175+
176+ void setup () {
177+ // put your setup code here, to run once:
178+ Serial.begin (115200 );
179+ Serial.println ();
180+
181+ setupWifi ();
182+ syncTimeFromNtp ();
183+
184+ // setup the gpio led
185+ setupLED ();
186+
187+ // setting up the device info i.e to be seen in the device shadow
188+ Bytebeam.status = " Device is Up!" ;
189+ Bytebeam.softwareType = " hello-wokwi-ino" ;
190+ Bytebeam.softwareVersion = " 1.0.0" ;
191+ Bytebeam.hardwareType = " ESP32 Dev Module" ;
192+ Bytebeam.hardwareVersion = " rev1" ;
193+
194+ // begin the bytebeam client
195+ if (!Bytebeam.begin (deviceConfigData, BytebeamLogger::LOG_INFO)) {
196+ Serial.println (" Bytebeam Client Initialization Failed." );
197+ } else {
198+ Serial.println (" Bytebeam Client is Initialized Successfully." );
199+ }
200+
201+ // add the handler for toggle led action
202+ Bytebeam.addActionHandler (ToggleLED_Hanlder, " ToggleLED" );
203+ }
204+
205+ void loop () {
206+ // put your main code here, to run repeatedly:
207+
208+ // bytebeam client loop
209+ Bytebeam.loop ();
210+
211+ // hold on the execution for some time
212+ delay (5000 );
213+ }
0 commit comments