3333#include < Arduino.h>
3434#include " ChronosESP32.h"
3535
36- #define SERVICE_UUID " 6e400001-b5a3-f393-e0a9-e50e24dcca9e"
37- #define CHARACTERISTIC_UUID_RX " 6e400002-b5a3-f393-e0a9-e50e24dcca9e"
38- #define CHARACTERISTIC_UUID_TX " 6e400003-b5a3-f393-e0a9-e50e24dcca9e"
39-
40- static BLECharacteristic *pCharacteristicTX;
41- static BLECharacteristic *pCharacteristicRX;
36+ BLECharacteristic *ChronosESP32::pCharacteristicTX;
37+ BLECharacteristic *ChronosESP32::pCharacteristicRX;
4238
4339/* !
4440 @brief Constructor for ChronosESP32
@@ -91,8 +87,8 @@ void ChronosESP32::begin()
9187 notifications[0 ].app = " Chronos" ;
9288 notifications[0 ].message = " Download from Google Play to sync time and receive notifications" ;
9389
94- findTimer.duration = 10000 ; // 10 seconds for find phone
95- ringerTimer.duration = 30000 ; // 30 seconds for ringer alert
90+ findTimer.duration = 30 * 1000 ; // 30 seconds for find phone
91+ ringerTimer.duration = 30 * 1000 ; // 30 seconds for ringer alert
9692}
9793
9894/* !
@@ -111,6 +107,7 @@ void ChronosESP32::loop()
111107
112108 sendInfo ();
113109 sendBattery ();
110+ setNotifyBattery (notifyPhone);
114111 }
115112 }
116113 if (findTimer.active )
@@ -316,9 +313,7 @@ void ChronosESP32::sendCommand(uint8_t *command, size_t length)
316313void ChronosESP32::musicControl (uint16_t command)
317314{
318315 uint8_t musicCmd[] = {0xAB , 0x00 , 0x04 , 0xFF , (uint8_t )(command >> 8 ), 0x80 , (uint8_t )(command)};
319- pCharacteristicTX->setValue (musicCmd, 7 );
320- pCharacteristicTX->notify ();
321- vTaskDelay (200 );
316+ sendCommand (musicCmd, 7 );
322317}
323318
324319/* !
@@ -329,9 +324,7 @@ void ChronosESP32::musicControl(uint16_t command)
329324void ChronosESP32::setVolume (uint8_t level)
330325{
331326 uint8_t volumeCmd[] = {0xAB , 0x00 , 0x05 , 0xFF , 0x99 , 0x80 , 0xA0 , level};
332- pCharacteristicTX->setValue (volumeCmd, 8 );
333- pCharacteristicTX->notify ();
334- vTaskDelay (200 );
327+ sendCommand (volumeCmd, 8 );
335328}
336329
337330/* !
@@ -342,9 +335,7 @@ bool ChronosESP32::capturePhoto()
342335 if (cameraReady)
343336 {
344337 uint8_t captureCmd[] = {0xAB , 0x00 , 0x04 , 0xFF , 0x79 , 0x80 , 0x01 };
345- pCharacteristicTX->setValue (captureCmd, 7 );
346- pCharacteristicTX->notify ();
347- vTaskDelay (200 );
338+ sendCommand (captureCmd, 7 );
348339 }
349340 return cameraReady;
350341}
@@ -363,9 +354,7 @@ void ChronosESP32::findPhone(bool state)
363354 }
364355 uint8_t c = state ? 0x01 : 0x00 ;
365356 uint8_t findCmd[] = {0xAB , 0x00 , 0x04 , 0xFF , 0x7D , 0x80 , c};
366- pCharacteristicTX->setValue (findCmd, 7 );
367- pCharacteristicTX->notify ();
368- vTaskDelay (200 );
357+ sendCommand (findCmd, 7 );
369358}
370359
371360/* !
@@ -404,7 +393,7 @@ String ChronosESP32::getAmPmC(bool caps)
404393 }
405394 else
406395 {
407- return this ->getAmPm (caps);
396+ return this ->getAmPm (! caps); // esp32time is getAmPm(bool lowercase );
408397 }
409398 return " " ;
410399}
@@ -463,20 +452,60 @@ void ChronosESP32::setRawDataCallback(void (*callback)(uint8_t *, int))
463452void ChronosESP32::sendInfo ()
464453{
465454 uint8_t infoCmd[] = {0xab , 0x00 , 0x11 , 0xff , 0x92 , 0xc0 , 0x01 , 0x00 , 0x00 , 0xfb , 0x1e , 0x40 , 0xc0 , 0x0e , 0x32 , 0x28 , 0x00 , 0xe2 , screenConf, 0x80 };
466- pCharacteristicTX->setValue (infoCmd, 20 );
467- pCharacteristicTX->notify ();
468- vTaskDelay (200 );
455+ sendCommand (infoCmd, 20 );
469456}
470457
471458/* !
472459 @brief send the battery level
473460*/
474461void ChronosESP32::sendBattery ()
475462{
476- uint8_t batCmd[] = {0xAB , 0x00 , 0x05 , 0xFF , 0x91 , 0x80 , isCharging ? 0x01 : 0x00 , batteryLevel};
477- pCharacteristicTX->setValue (batCmd, 8 );
478- pCharacteristicTX->notify ();
479- vTaskDelay (200 );
463+ uint8_t c = isCharging ? 0x01 : 0x00 ;
464+ uint8_t batCmd[] = {0xAB , 0x00 , 0x05 , 0xFF , 0x91 , 0x80 , c, batteryLevel};
465+ sendCommand (batCmd, 8 );
466+ }
467+
468+ /* !
469+ @brief request the battery level of the phone
470+ */
471+ void ChronosESP32::setNotifyBattery (bool state)
472+ {
473+ notifyPhone = state;
474+ uint8_t s = state ? 0x01 : 0x00 ;
475+ uint8_t batRq[] = {0xAB , 0x00 , 0x04 , 0xFE , 0x91 , 0x80 , s}; // custom command AB..FE
476+ sendCommand (batRq, 7 );
477+ }
478+
479+ /* !
480+ @brief charging status of the phone
481+ */
482+ bool ChronosESP32::isPhoneCharging ()
483+ {
484+ return phoneCharging;
485+ }
486+
487+ /* !
488+ @brief battery level of the phone
489+ */
490+ uint8_t ChronosESP32::getPhoneBattery ()
491+ {
492+ return phoneBatteryLevel;
493+ }
494+
495+ /* !
496+ @brief app version code
497+ */
498+ int ChronosESP32::getAppCode ()
499+ {
500+ return appCode;
501+ }
502+ /* !
503+ @brief app version name
504+ */
505+
506+ String ChronosESP32::getAppVersion ()
507+ {
508+ return appVersion;
480509}
481510
482511/* !
@@ -529,7 +558,7 @@ String ChronosESP32::appName(int id)
529558 case 0x22 :
530559 return " WearFit Pro" ;
531560 case 0xC0 :
532- return " ChronosESP32 " ;
561+ return " Chronos " ;
533562 default :
534563 return " Message" ;
535564 }
@@ -583,7 +612,7 @@ void ChronosESP32::onWrite(BLECharacteristic *pCharacteristic)
583612 rawDataReceivedCallback ((uint8_t *)pData.data (), len);
584613 }
585614
586- if ((pData[0 ] == 0xAB || pData[0 ] == 0xEA ) && pData[3 ] == 0xFF )
615+ if ((pData[0 ] == 0xAB || pData[0 ] == 0xEA ) && ( pData[3 ] == 0xFE || pData[ 3 ] == 0xFF ) )
587616 {
588617 // start of data, assign length from packet
589618 incomingData.length = pData[1 ] * 256 + pData[2 ] + 3 ;
@@ -702,19 +731,19 @@ void ChronosESP32::dataReceived()
702731 }
703732 break ;
704733 }
705- if (state == 0x02 ){
734+ if (state == 0x02 )
735+ {
706736 notificationIndex++;
707737 notifications[notificationIndex % NOTIF_SIZE].icon = icon;
708738 notifications[notificationIndex % NOTIF_SIZE].app = appName (icon);
709739 notifications[notificationIndex % NOTIF_SIZE].time = this ->getTime (" %H:%M" );
710740 notifications[notificationIndex % NOTIF_SIZE].message = message;
711-
741+
712742 if (notificationReceivedCallback != nullptr )
713743 {
714744 notificationReceivedCallback (notifications[notificationIndex % NOTIF_SIZE]);
715745 }
716746 }
717-
718747 }
719748 break ;
720749 case 0x73 :
@@ -868,6 +897,19 @@ void ChronosESP32::dataReceived()
868897 uint32_t slp = ((uint32_t )hour << 24 ) | ((uint32_t )minute << 16 ) | ((uint32_t )hour2 << 8 ) | ((uint32_t )minute2);
869898 configurationReceivedCallback (CF_SLEEP, enabled, slp);
870899 }
900+ break ;
901+ case 0x91 :
902+
903+ if (incomingData.data [3 ] == 0xFE )
904+ {
905+ phoneCharging = incomingData.data [6 ] == 1 ;
906+ phoneBatteryLevel = incomingData.data [7 ];
907+ if (configurationReceivedCallback != nullptr )
908+ {
909+ configurationReceivedCallback (CF_PBAT, incomingData.data [6 ], phoneBatteryLevel);
910+ }
911+ }
912+
871913 break ;
872914 case 0x93 :
873915 this ->setTime (incomingData.data [13 ], incomingData.data [12 ], incomingData.data [11 ], incomingData.data [10 ], incomingData.data [9 ], incomingData.data [7 ] * 256 + incomingData.data [8 ]);
@@ -885,6 +927,21 @@ void ChronosESP32::dataReceived()
885927 configurationReceivedCallback (CF_FONT, color, select);
886928 }
887929 break ;
930+ case 0xCA :
931+ if (incomingData.data [3 ] == 0xFE )
932+ {
933+ appCode = (incomingData.data [6 ] * 256 ) + incomingData.data [7 ];
934+ appVersion = " " ;
935+ for (int i = 8 ; i < len; i++)
936+ {
937+ appVersion += (char )incomingData.data [i];
938+ }
939+ if (configurationReceivedCallback != nullptr )
940+ {
941+ configurationReceivedCallback (CF_APP, appCode, 0 );
942+ }
943+ }
944+ break ;
888945 }
889946 }
890947 else if (incomingData.data [0 ] == 0xEA )
0 commit comments