@@ -60,13 +60,10 @@ unsigned long getTime()
60
60
ArduinoIoTCloudTCP::ArduinoIoTCloudTCP ()
61
61
: _state{State::ConnectPhy}
62
62
, _connection_attempt(0 ,0 )
63
+ , _message_stream(std::bind(&ArduinoIoTCloudTCP::sendMessage, this , std::placeholders::_1))
64
+ , _thing(&_message_stream)
65
+ , _thing_id_property{nullptr }
63
66
, _device_property_container{0 }
64
- , _thing_property_container{0 }
65
- , _last_checked_property_index{0 }
66
- , _tz_offset{0 }
67
- , _tz_offset_property{nullptr }
68
- , _tz_dst_until{0 }
69
- , _tz_dst_until_property{nullptr }
70
67
, _mqtt_data_buf{0 }
71
68
, _mqtt_data_len{0 }
72
69
, _mqtt_data_request_retransmit{false }
@@ -214,10 +211,8 @@ int ArduinoIoTCloudTCP::begin(bool const enable_watchdog, String brokerAddress,
214
211
#endif /* OTA_ENABLED */
215
212
p = new CloudWrapperString (_thing_id);
216
213
_thing_id_property = &addPropertyToContainer (_device_property_container, *p, " thing_id" , Permission::ReadWrite, -1 ).writeOnDemand ();
217
- p = new CloudWrapperInt (_tz_offset);
218
- _tz_offset_property = &addPropertyToContainer (_thing_property_container, *p, " tz_offset" , Permission::ReadWrite, -1 ).writeOnDemand ();
219
- p = new CloudWrapperUnsignedInt (_tz_dst_until);
220
- _tz_dst_until_property = &addPropertyToContainer (_thing_property_container, *p, " tz_dst_until" , Permission::ReadWrite, -1 ).writeOnDemand ();
214
+
215
+ _thing.begin ();
221
216
222
217
#if OTA_ENABLED
223
218
_ota_cap = OTA::isCapable ();
@@ -274,7 +269,6 @@ void ArduinoIoTCloudTCP::update()
274
269
case State::SubscribeDeviceTopic: next_state = handle_SubscribeDeviceTopic (); break ;
275
270
case State::CheckDeviceConfig: next_state = handle_CheckDeviceConfig (); break ;
276
271
case State::SubscribeThingTopics: next_state = handle_SubscribeThingTopics (); break ;
277
- case State::RequestLastValues: next_state = handle_RequestLastValues (); break ;
278
272
case State::Connected: next_state = handle_Connected (); break ;
279
273
case State::Disconnect: next_state = handle_Disconnect (); break ;
280
274
}
@@ -328,12 +322,13 @@ ArduinoIoTCloudTCP::State ArduinoIoTCloudTCP::handle_ConnectPhy()
328
322
329
323
ArduinoIoTCloudTCP::State ArduinoIoTCloudTCP::handle_SyncTime ()
330
324
{
331
- #pragma GCC diagnostic push
332
- #pragma GCC diagnostic ignored "-Wunused-variable"
333
- unsigned long const internal_posix_time = _time_service.getTime ();
334
- #pragma GCC diagnostic pop
335
- DEBUG_VERBOSE (" ArduinoIoTCloudTCP::%s internal clock configured to posix timestamp %d" , __FUNCTION__, internal_posix_time);
336
- return State::ConnectMqttBroker;
325
+ if (TimeServiceClass::isTimeValid (getTime ()))
326
+ {
327
+ DEBUG_VERBOSE (" ArduinoIoTCloudTCP::%s internal clock configured to posix timestamp %d" , __FUNCTION__, getTime ());
328
+ return State::ConnectMqttBroker;
329
+ }
330
+
331
+ return State::ConnectPhy;
337
332
}
338
333
339
334
ArduinoIoTCloudTCP::State ArduinoIoTCloudTCP::handle_ConnectMqttBroker ()
@@ -477,38 +472,12 @@ ArduinoIoTCloudTCP::State ArduinoIoTCloudTCP::handle_SubscribeThingTopics()
477
472
478
473
/* Successfully subscribed to thing topics, reconfigure timers for next state and go on */
479
474
_connection_attempt.begin (AIOT_CONFIG_TIMEOUT_FOR_LASTVALUES_SYNC_ms);
480
- return State::RequestLastValues;
481
- }
482
-
483
- ArduinoIoTCloudTCP::State ArduinoIoTCloudTCP::handle_RequestLastValues ()
484
- {
485
- if (!_mqttClient.connected () || _thing_id_property->isDifferentFromCloud ())
486
- {
487
- return State::Disconnect;
488
- }
489
-
490
- /* Check whether or not we need to send a new request. */
491
- if (_connection_attempt.isRetry () && !_connection_attempt.isExpired ())
492
- return State::RequestLastValues;
493
-
494
- /* Track the number of times a get-last-values request was sent to the cloud.
495
- * If no data is received within a certain number of retry-requests it's a better
496
- * strategy to disconnect and re-establish connection from the ground up.
497
- */
498
- if (_connection_attempt.getRetryCount () > AIOT_CONFIG_LASTVALUES_SYNC_MAX_RETRY_CNT)
499
- {
500
- return State::Disconnect;
501
- }
502
-
503
- _connection_attempt.retry ();
504
- requestLastValue ();
505
- DEBUG_VERBOSE (" ArduinoIoTCloudTCP::%s [%d] last values requested" , __FUNCTION__, _time_service.getTime ());
506
- return State::RequestLastValues;
475
+ return State::Connected;
507
476
}
508
477
509
478
ArduinoIoTCloudTCP::State ArduinoIoTCloudTCP::handle_Connected ()
510
479
{
511
- if (!_mqttClient.connected ())
480
+ if (!_mqttClient.connected () || _thing_id_property-> isDifferentFromCloud () || !_thing. connected () )
512
481
{
513
482
/* The last message was definitely lost, trigger a retransmit. */
514
483
_mqtt_data_request_retransmit = true ;
@@ -517,20 +486,6 @@ ArduinoIoTCloudTCP::State ArduinoIoTCloudTCP::handle_Connected()
517
486
/* We are connected so let's to our stuff here. */
518
487
else
519
488
{
520
- if (_thing_id_property->isDifferentFromCloud ())
521
- {
522
- return State::Disconnect;
523
- }
524
-
525
- /* Check if a primitive property wrapper is locally changed.
526
- * This function requires an existing time service which in
527
- * turn requires an established connection. Not having that
528
- * leads to a wrong time set in the time service which inhibits
529
- * the connection from being established due to a wrong data
530
- * in the reconstructed certificate.
531
- */
532
- updateTimestampOnLocallyChangedProperties (_thing_property_container);
533
-
534
489
/* Retransmit data in case there was a lost transaction due
535
490
* to phy layer or MQTT connectivity loss.
536
491
*/
@@ -539,27 +494,11 @@ ArduinoIoTCloudTCP::State ArduinoIoTCloudTCP::handle_Connected()
539
494
_mqtt_data_request_retransmit = false ;
540
495
}
541
496
542
- /* Configure Time service with timezone data:
543
- * _tz_offset [offset + dst]
544
- * _tz_dst_until [posix timestamp until _tz_offset is valid]
545
- */
546
- if (_tz_offset_property->isDifferentFromCloud () || _tz_dst_until_property->isDifferentFromCloud ()) {
547
- _tz_offset_property->fromCloudToLocal ();
548
- _tz_dst_until_property->fromCloudToLocal ();
549
- _time_service.setTimeZoneData (_tz_offset, _tz_dst_until);
550
- }
497
+ /* Call CloudThing process to synchronize properties */
498
+ _thing.update ();
551
499
552
- /* Check if any properties need encoding and send them to
553
- * the cloud if necessary.
554
- */
555
- sendThingPropertiesToCloud ();
500
+ return State::Connected;
556
501
557
- unsigned long const internal_posix_time = _time_service.getTime ();
558
- if (internal_posix_time < _tz_dst_until) {
559
- return State::Connected;
560
- } else {
561
- return State::RequestLastValues;
562
- }
563
502
}
564
503
}
565
504
@@ -604,9 +543,15 @@ ArduinoIoTCloudTCP::State ArduinoIoTCloudTCP::handle_Disconnect()
604
543
/* TODO add device topic */
605
544
_mqttClient.stop ();
606
545
}
546
+
547
+ Message message = { ResetCmdId };
548
+ _thing.handleMessage (&message);
549
+
607
550
DEBUG_INFO (" Disconnected from Arduino IoT Cloud" );
608
551
execCloudEventCallback (ArduinoIoTCloudEvent::DISCONNECT);
609
552
553
+ updateThingTopics ();
554
+
610
555
/* Setup timer for broker connection and restart */
611
556
_connection_attempt.begin (AIOT_CONFIG_RECONNECTION_RETRY_DELAY_ms, AIOT_CONFIG_MAX_RECONNECTION_RETRY_DELAY_ms);
612
557
return State::ConnectPhy;
@@ -630,25 +575,47 @@ void ArduinoIoTCloudTCP::handleMessage(int length)
630
575
/* Topic for OTA properties and device configuration */
631
576
if (_deviceTopicIn == topic) {
632
577
CBORDecoder::decode (_device_property_container, (uint8_t *)bytes, length);
633
- _state = State::CheckDeviceConfig;
578
+ if (_thing_id_property->isDifferentFromCloud () && (_thing_id.length () != 0 )) {
579
+ _state = State::Disconnect;
580
+ } else {
581
+ _state = State::CheckDeviceConfig;
582
+ }
634
583
}
635
584
636
585
/* Topic for user input data */
637
586
if (_dataTopicIn == topic) {
638
- CBORDecoder::decode (_thing_property_container , (uint8_t *)bytes, length);
587
+ CBORDecoder::decode (_thing. getPropertyContainer () , (uint8_t *)bytes, length);
639
588
}
640
589
641
590
/* Topic for sync Thing last values on connect */
642
- if (( _shadowTopicIn == topic) && (_state == State::RequestLastValues) )
591
+ if (_shadowTopicIn == topic)
643
592
{
644
593
DEBUG_VERBOSE (" ArduinoIoTCloudTCP::%s [%d] last values received" , __FUNCTION__, millis ());
645
- CBORDecoder::decode (_thing_property_container, (uint8_t *)bytes, length, true );
646
- _time_service.setTimeZoneData (_tz_offset, _tz_dst_until);
594
+ CBORDecoder::decode (_thing.getPropertyContainer (), (uint8_t *)bytes, length, true );
595
+ Message message = { LastValuesUpdateCmdId };
596
+ _thing.handleMessage (&message);
647
597
execCloudEventCallback (ArduinoIoTCloudEvent::SYNC);
648
598
_state = State::Connected;
649
599
}
650
600
}
651
601
602
+ void ArduinoIoTCloudTCP::sendMessage (Message * msg)
603
+ {
604
+ switch (msg->id )
605
+ {
606
+ case PropertiesUpdateCmdId:
607
+ sendThingPropertiesToCloud ();
608
+ break ;
609
+
610
+ case LastValuesBeginCmdId:
611
+ requestLastValue ();
612
+ break ;
613
+
614
+ default :
615
+ break ;
616
+ }
617
+ }
618
+
652
619
void ArduinoIoTCloudTCP::sendPropertyContainerToCloud (String const topic, PropertyContainer & property_container, unsigned int & current_property_index)
653
620
{
654
621
int bytes_encoded = 0 ;
@@ -669,7 +636,7 @@ void ArduinoIoTCloudTCP::sendPropertyContainerToCloud(String const topic, Proper
669
636
670
637
void ArduinoIoTCloudTCP::sendThingPropertiesToCloud ()
671
638
{
672
- sendPropertyContainerToCloud (_dataTopicOut, _thing_property_container, _last_checked_property_index );
639
+ sendPropertyContainerToCloud (_dataTopicOut, _thing. getPropertyContainer (), _thing. getPropertyContainerIndex () );
673
640
}
674
641
675
642
void ArduinoIoTCloudTCP::sendDevicePropertiesToCloud ()
0 commit comments