@@ -509,6 +509,7 @@ bool BytebeamArduino::setupBytebeamClient() {
509509 this ->secureClient .setClientRSACert (this ->clientCert , this ->clientKey );
510510#endif
511511
512+ PubSubClient::setBufferSize ((uint16_t )384 );
512513 PubSubClient::setClient (this ->secureClient );
513514 PubSubClient::setCallback (BytebeamActionsCallback);
514515 PubSubClient::setServer (this ->mqttBrokerUrl , this ->mqttPort );
@@ -619,6 +620,11 @@ bool BytebeamArduino::initSDK() {
619620 BytebeamLogger::Info (__FILE__, __func__, " Skipped Bytebeam OTA from compilation phase i.e saving flash size" );
620621#endif
621622
623+ // publish the device heartbeat
624+ if (!publishDeviceHeartbeat ()) {
625+ BytebeamLogger::Error (__FILE__, __func__, " Failed to publish device heartbeat." );
626+ }
627+
622628 BytebeamLogger::Info (__FILE__, __func__, " Bytebeam Client Initialized Successfully !\n " );
623629
624630 return true ;
@@ -629,6 +635,91 @@ bool BytebeamArduino::isInitialized() {
629635 return this ->isClientActive ;
630636}
631637
638+ bool BytebeamArduino::publishDeviceHeartbeat () {
639+ static int sequence = 0 ;
640+ unsigned long long milliseconds = 0 ;
641+ const char * rebootReasonStr = " " ;
642+ unsigned long long uptime = 0 ;
643+ const char * payload = " " ;
644+ String deviceShadowStr = " " ;
645+ StaticJsonDocument<1024 > doc;
646+
647+ // get the current epoch millis
648+ if (!BytebeamTime.getEpochMillis ()) {
649+ BytebeamLogger::Error (__FILE__, __func__, " failed to get epoch millis" );
650+ return false ;
651+ }
652+
653+ sequence++;
654+ milliseconds = BytebeamTime.nowMillis ;
655+ uptime = millis ();
656+
657+ #ifdef BYTEBEAM_ARDUINO_ARCH_ESP32
658+ esp_reset_reason_t reboot_reason_id = esp_reset_reason ();
659+
660+ switch (reboot_reason_id) {
661+ case ESP_RST_UNKNOWN : rebootReasonStr = " Unknown Reset" ; break ;
662+ case ESP_RST_POWERON : rebootReasonStr = " Power On Reset" ; break ;
663+ case ESP_RST_EXT : rebootReasonStr = " External Pin Reset" ; break ;
664+ case ESP_RST_SW : rebootReasonStr = " Software Reset" ; break ;
665+ case ESP_RST_PANIC : rebootReasonStr = " Hard Fault Reset" ; break ;
666+ case ESP_RST_INT_WDT : rebootReasonStr = " Interrupt Watchdog Reset" ; break ;
667+ case ESP_RST_TASK_WDT : rebootReasonStr = " Task Watchdog Reset" ; break ;
668+ case ESP_RST_WDT : rebootReasonStr = " Other Watchdog Reset" ; break ;
669+ case ESP_RST_DEEPSLEEP : rebootReasonStr = " Exiting Deep Sleep Reset" ; break ;
670+ case ESP_RST_BROWNOUT : rebootReasonStr = " Brownout Reset" ; break ;
671+ case ESP_RST_SDIO : rebootReasonStr = " SDIO Reset" ; break ;
672+
673+ default : rebootReasonStr = " Unknown Reset Id" ;
674+ }
675+ #endif
676+
677+ #ifdef BYTEBEAM_ARDUINO_ARCH_ESP8266
678+ rebootReasonStr = ESP.getResetReason ().c_str ();
679+ #endif
680+
681+ // if status is not provided append the dummy one showing device activity
682+ if (this ->status == NULL ) {
683+ this ->status = " Device is Active!" ;
684+ }
685+
686+ JsonArray deviceShadowJsonArray = doc.to <JsonArray>();
687+ JsonObject deviceShadowJsonObj_1 = deviceShadowJsonArray.createNestedObject ();
688+
689+ deviceShadowJsonObj_1[" timestamp" ] = milliseconds;
690+ deviceShadowJsonObj_1[" sequence" ] = sequence;
691+ deviceShadowJsonObj_1[" Reset_Reason" ] = rebootReasonStr;
692+ deviceShadowJsonObj_1[" Uptime" ] = uptime;
693+ deviceShadowJsonObj_1[" Status" ] = this ->status ;
694+
695+ // if software type is provided append it else leave
696+ if (this ->softwareType != NULL ) {
697+ deviceShadowJsonObj_1[" Software_Type" ] = this ->softwareType ;
698+ }
699+
700+ // if software version is provided append it else leave
701+ if (this ->softwareVersion != NULL ) {
702+ deviceShadowJsonObj_1[" Software_Version" ] = this ->softwareVersion ;
703+ }
704+
705+ // if hardware type is provided append it else leave
706+ if (this ->hardwareType != NULL ) {
707+ deviceShadowJsonObj_1[" Hardware_Type" ] = this ->hardwareType ;
708+ }
709+
710+ // if hardware version is provided append it else leave
711+ if (this ->hardwareVersion != NULL ) {
712+ deviceShadowJsonObj_1[" Hardware_Version" ] = this ->hardwareVersion ;
713+ }
714+
715+ serializeJson (deviceShadowJsonArray, deviceShadowStr);
716+ payload = deviceShadowStr.c_str ();
717+
718+ BytebeamLogger::Info (__FILE__, __func__, " publishing device heartbeat." );
719+
720+ return Bytebeam.publishToStream (" device_shadow" , payload);
721+ }
722+
632723BytebeamArduino::BytebeamArduino ()
633724 #ifdef BYTEBEAM_ARDUINO_USE_MODEM
634725 : secureClient(&gsmClient)
@@ -653,6 +744,12 @@ BytebeamArduino::BytebeamArduino()
653744
654745 this ->isClientActive = false ;
655746 this ->isOTAEnable = false ;
747+
748+ this ->status = NULL ;
749+ this ->softwareType = NULL ;
750+ this ->softwareVersion = NULL ;
751+ this ->hardwareType = NULL ;
752+ this ->hardwareVersion = NULL ;
656753}
657754
658755BytebeamArduino::~BytebeamArduino () {
@@ -1212,6 +1309,12 @@ bool BytebeamArduino::end() {
12121309
12131310 clearBytebeamClient ();
12141311
1312+ this ->status = NULL ;
1313+ this ->softwareType = NULL ;
1314+ this ->softwareVersion = NULL ;
1315+ this ->hardwareType = NULL ;
1316+ this ->hardwareVersion = NULL ;
1317+
12151318 // log bytebeam client duration to serial :)
12161319 BytebeamLogger::Error (__FILE__, __func__, " Bytebeam Client Duration : %d ms" , BytebeamTime.durationMillis );
12171320
0 commit comments