Skip to content

Commit 0d69bbb

Browse files
committed
ArduinoIoTCloudTCP: adapt state machine to use Thing process
1 parent 20831f5 commit 0d69bbb

File tree

4 files changed

+50
-92
lines changed

4 files changed

+50
-92
lines changed

src/ArduinoIoTCloud.cpp

-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ ArduinoIoTCloudClass::ArduinoIoTCloudClass()
2929
: _connection{nullptr}
3030
, _time_service(TimeService)
3131
, _thing_id{""}
32-
, _thing_id_property{nullptr}
3332
, _lib_version{AIOT_CONFIG_LIB_VERSION}
3433
, _device_id{""}
3534
, _cloud_event_callback{nullptr}

src/ArduinoIoTCloud.h

-1
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,6 @@ class ArduinoIoTCloudClass
148148
ConnectionHandler * _connection;
149149
TimeServiceClass & _time_service;
150150
String _thing_id;
151-
Property * _thing_id_property;
152151
String _lib_version;
153152

154153
void execCloudEventCallback(ArduinoIoTCloudEvent const event);

src/ArduinoIoTCloudTCP.cpp

+44-78
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,10 @@ unsigned long getTime()
6060
ArduinoIoTCloudTCP::ArduinoIoTCloudTCP()
6161
: _state{State::ConnectPhy}
6262
, _connection_attempt(0,0)
63+
, _message_stream(std::bind(&ArduinoIoTCloudTCP::sendMessage, this, std::placeholders::_1))
64+
, _thing(&_message_stream)
65+
, _thing_id_property{nullptr}
6366
, _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}
7067
, _mqtt_data_buf{0}
7168
, _mqtt_data_len{0}
7269
, _mqtt_data_request_retransmit{false}
@@ -214,10 +211,8 @@ int ArduinoIoTCloudTCP::begin(bool const enable_watchdog, String brokerAddress,
214211
#endif /* OTA_ENABLED */
215212
p = new CloudWrapperString(_thing_id);
216213
_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();
221216

222217
#if OTA_ENABLED
223218
_ota_cap = OTA::isCapable();
@@ -274,7 +269,6 @@ void ArduinoIoTCloudTCP::update()
274269
case State::SubscribeDeviceTopic: next_state = handle_SubscribeDeviceTopic(); break;
275270
case State::CheckDeviceConfig: next_state = handle_CheckDeviceConfig(); break;
276271
case State::SubscribeThingTopics: next_state = handle_SubscribeThingTopics(); break;
277-
case State::RequestLastValues: next_state = handle_RequestLastValues(); break;
278272
case State::Connected: next_state = handle_Connected(); break;
279273
case State::Disconnect: next_state = handle_Disconnect(); break;
280274
}
@@ -478,38 +472,12 @@ ArduinoIoTCloudTCP::State ArduinoIoTCloudTCP::handle_SubscribeThingTopics()
478472

479473
/* Successfully subscribed to thing topics, reconfigure timers for next state and go on */
480474
_connection_attempt.begin(AIOT_CONFIG_TIMEOUT_FOR_LASTVALUES_SYNC_ms);
481-
return State::RequestLastValues;
482-
}
483-
484-
ArduinoIoTCloudTCP::State ArduinoIoTCloudTCP::handle_RequestLastValues()
485-
{
486-
if (!_mqttClient.connected() || _thing_id_property->isDifferentFromCloud())
487-
{
488-
return State::Disconnect;
489-
}
490-
491-
/* Check whether or not we need to send a new request. */
492-
if (_connection_attempt.isRetry() && !_connection_attempt.isExpired())
493-
return State::RequestLastValues;
494-
495-
/* Track the number of times a get-last-values request was sent to the cloud.
496-
* If no data is received within a certain number of retry-requests it's a better
497-
* strategy to disconnect and re-establish connection from the ground up.
498-
*/
499-
if (_connection_attempt.getRetryCount() > AIOT_CONFIG_LASTVALUES_SYNC_MAX_RETRY_CNT)
500-
{
501-
return State::Disconnect;
502-
}
503-
504-
_connection_attempt.retry();
505-
requestLastValue();
506-
DEBUG_VERBOSE("ArduinoIoTCloudTCP::%s [%d] last values requested", __FUNCTION__, _time_service.getTime());
507-
return State::RequestLastValues;
475+
return State::Connected;
508476
}
509477

510478
ArduinoIoTCloudTCP::State ArduinoIoTCloudTCP::handle_Connected()
511479
{
512-
if (!_mqttClient.connected())
480+
if (!_mqttClient.connected() || _thing_id_property->isDifferentFromCloud() || !_thing.connected())
513481
{
514482
/* The last message was definitely lost, trigger a retransmit. */
515483
_mqtt_data_request_retransmit = true;
@@ -518,20 +486,6 @@ ArduinoIoTCloudTCP::State ArduinoIoTCloudTCP::handle_Connected()
518486
/* We are connected so let's to our stuff here. */
519487
else
520488
{
521-
if (_thing_id_property->isDifferentFromCloud())
522-
{
523-
return State::Disconnect;
524-
}
525-
526-
/* Check if a primitive property wrapper is locally changed.
527-
* This function requires an existing time service which in
528-
* turn requires an established connection. Not having that
529-
* leads to a wrong time set in the time service which inhibits
530-
* the connection from being established due to a wrong data
531-
* in the reconstructed certificate.
532-
*/
533-
updateTimestampOnLocallyChangedProperties(_thing_property_container);
534-
535489
/* Retransmit data in case there was a lost transaction due
536490
* to phy layer or MQTT connectivity loss.
537491
*/
@@ -540,27 +494,11 @@ ArduinoIoTCloudTCP::State ArduinoIoTCloudTCP::handle_Connected()
540494
_mqtt_data_request_retransmit = false;
541495
}
542496

543-
/* Configure Time service with timezone data:
544-
* _tz_offset [offset + dst]
545-
* _tz_dst_until [posix timestamp until _tz_offset is valid]
546-
*/
547-
if (_tz_offset_property->isDifferentFromCloud() || _tz_dst_until_property->isDifferentFromCloud()) {
548-
_tz_offset_property->fromCloudToLocal();
549-
_tz_dst_until_property->fromCloudToLocal();
550-
_time_service.setTimeZoneData(_tz_offset, _tz_dst_until);
551-
}
497+
/* Call CloudThing process to synchronize properties */
498+
_thing.update();
552499

553-
/* Check if any properties need encoding and send them to
554-
* the cloud if necessary.
555-
*/
556-
sendThingPropertiesToCloud();
500+
return State::Connected;
557501

558-
unsigned long const internal_posix_time = _time_service.getTime();
559-
if (internal_posix_time < _tz_dst_until) {
560-
return State::Connected;
561-
} else {
562-
return State::RequestLastValues;
563-
}
564502
}
565503
}
566504

@@ -605,9 +543,15 @@ ArduinoIoTCloudTCP::State ArduinoIoTCloudTCP::handle_Disconnect()
605543
/* TODO add device topic */
606544
_mqttClient.stop();
607545
}
546+
547+
Message message = { ResetCmdId };
548+
_thing.handleMessage(&message);
549+
608550
DEBUG_INFO("Disconnected from Arduino IoT Cloud");
609551
execCloudEventCallback(ArduinoIoTCloudEvent::DISCONNECT);
610552

553+
updateThingTopics();
554+
611555
/* Setup timer for broker connection and restart */
612556
_connection_attempt.begin(AIOT_CONFIG_RECONNECTION_RETRY_DELAY_ms, AIOT_CONFIG_MAX_RECONNECTION_RETRY_DELAY_ms);
613557
return State::ConnectPhy;
@@ -631,25 +575,47 @@ void ArduinoIoTCloudTCP::handleMessage(int length)
631575
/* Topic for OTA properties and device configuration */
632576
if (_deviceTopicIn == topic) {
633577
CBORDecoder::decode(_device_property_container, (uint8_t*)bytes, length);
634-
_state = State::CheckDeviceConfig;
578+
if (_thing_id_property->isDifferentFromCloud() && (_thing_id.length() != 0)) {
579+
_state = State::Disconnect;
580+
} else {
581+
_state = State::CheckDeviceConfig;
582+
}
635583
}
636584

637585
/* Topic for user input data */
638586
if (_dataTopicIn == topic) {
639-
CBORDecoder::decode(_thing_property_container, (uint8_t*)bytes, length);
587+
CBORDecoder::decode(_thing.getPropertyContainer(), (uint8_t*)bytes, length);
640588
}
641589

642590
/* Topic for sync Thing last values on connect */
643-
if ((_shadowTopicIn == topic) && (_state == State::RequestLastValues))
591+
if (_shadowTopicIn == topic)
644592
{
645593
DEBUG_VERBOSE("ArduinoIoTCloudTCP::%s [%d] last values received", __FUNCTION__, millis());
646-
CBORDecoder::decode(_thing_property_container, (uint8_t*)bytes, length, true);
647-
_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);
648597
execCloudEventCallback(ArduinoIoTCloudEvent::SYNC);
649598
_state = State::Connected;
650599
}
651600
}
652601

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+
653619
void ArduinoIoTCloudTCP::sendPropertyContainerToCloud(String const topic, PropertyContainer & property_container, unsigned int & current_property_index)
654620
{
655621
int bytes_encoded = 0;
@@ -670,7 +636,7 @@ void ArduinoIoTCloudTCP::sendPropertyContainerToCloud(String const topic, Proper
670636

671637
void ArduinoIoTCloudTCP::sendThingPropertiesToCloud()
672638
{
673-
sendPropertyContainerToCloud(_dataTopicOut, _thing_property_container, _last_checked_property_index);
639+
sendPropertyContainerToCloud(_dataTopicOut, _thing.getPropertyContainer(), _thing.getPropertyContainerIndex());
674640
}
675641

676642
void ArduinoIoTCloudTCP::sendDevicePropertiesToCloud()

src/ArduinoIoTCloudTCP.h

+6-12
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
#include <AIoTC_Config.h>
2626
#include <ArduinoIoTCloud.h>
2727
#include <ArduinoMqttClient.h>
28-
#include <utility/time/TimedAttempt.h>
28+
#include <ArduinoIoTCloudThing.h>
2929

3030
#if defined(BOARD_HAS_SECURE_ELEMENT)
3131
#include <Arduino_SecureElement.h>
@@ -75,7 +75,6 @@ class ArduinoIoTCloudTCP: public ArduinoIoTCloudClass
7575
ArduinoIoTCloudTCP();
7676
virtual ~ArduinoIoTCloudTCP() { }
7777

78-
7978
virtual void update () override;
8079
virtual int connected () override;
8180
virtual void printDebugInfo() override;
@@ -91,7 +90,7 @@ class ArduinoIoTCloudTCP: public ArduinoIoTCloudClass
9190
inline String getBrokerAddress() const { return _brokerAddress; }
9291
inline uint16_t getBrokerPort () const { return _brokerPort; }
9392

94-
inline PropertyContainer &getThingPropertyContainer() { return _thing_property_container; }
93+
inline PropertyContainer &getThingPropertyContainer() { return _thing.getPropertyContainer(); }
9594

9695
#if OTA_ENABLED
9796
/* The callback is triggered when the OTA is initiated and it gets executed until _ota_req flag is cleared.
@@ -118,21 +117,16 @@ class ArduinoIoTCloudTCP: public ArduinoIoTCloudClass
118117
SubscribeDeviceTopic,
119118
CheckDeviceConfig,
120119
SubscribeThingTopics,
121-
RequestLastValues,
122120
Connected,
123121
Disconnect,
124122
};
125123

126124
State _state;
127125
TimedAttempt _connection_attempt;
126+
MessageStream _message_stream;
127+
ArduinoCloudThing _thing;
128+
Property * _thing_id_property;
128129
PropertyContainer _device_property_container;
129-
PropertyContainer _thing_property_container;
130-
unsigned int _last_checked_property_index;
131-
132-
int _tz_offset;
133-
Property * _tz_offset_property;
134-
unsigned int _tz_dst_until;
135-
Property * _tz_dst_until_property;
136130

137131
String _brokerAddress;
138132
uint16_t _brokerPort;
@@ -200,12 +194,12 @@ class ArduinoIoTCloudTCP: public ArduinoIoTCloudClass
200194
State handle_CheckDeviceConfig();
201195
State handle_SubscribeDeviceTopic();
202196
State handle_SubscribeThingTopics();
203-
State handle_RequestLastValues();
204197
State handle_Connected();
205198
State handle_Disconnect();
206199

207200
static void onMessage(int length);
208201
void handleMessage(int length);
202+
void sendMessage(Message * msg);
209203
void sendPropertyContainerToCloud(String const topic, PropertyContainer & property_container, unsigned int & current_property_index);
210204
void sendThingPropertiesToCloud();
211205
void sendDevicePropertiesToCloud();

0 commit comments

Comments
 (0)