Skip to content
This repository was archived by the owner on Aug 18, 2020. It is now read-only.

Commit 4971060

Browse files
Merge pull request #33 from arduino-libraries/multi-value-properties
Multi value properties management
2 parents 8f27ffa + d1a8a76 commit 4971060

33 files changed

+2239
-951
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,5 @@ CMakeCache.txt
1212
cmake_install.cmake
1313
Makefile
1414

15-
.vscode/
15+
.vscode
16+
.vs

keywords.txt

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,28 +7,33 @@
77
#######################################
88

99
ArduinoCloudThing KEYWORD1
10+
CloudBool KEYWORD1
11+
CloudInt KEYWORD1
12+
CloudFloat KEYWORD1
13+
CloudString KEYWORD1
14+
1015

1116
#######################################
1217
# Methods and Functions (KEYWORD2)
1318
#######################################
1419

15-
begin KEYWORD2
16-
encode KEYWORD2
17-
decode KEYWORD2
18-
addPropertyReal KEYWORD2
19-
updateTimestampOnChangedProperties KEYWORD2
20+
begin KEYWORD2
21+
encode KEYWORD2
22+
decode KEYWORD2
23+
addPropertyReal KEYWORD2
24+
updateTimestampOnChangedProperties KEYWORD2
2025

2126
#######################################
2227
# Constants (LITERAL1)
2328
#######################################
2429

25-
ON LITERAL1
26-
OFF LITERAL1
27-
ON_CHANGE LITERAL1
28-
SECONDS LITERAL1
29-
MINUTES LITERAL1
30-
HOURS LITERAL1
31-
DAYS LITERAL1
32-
AUTO_SYNC LITERAL1
33-
FORCE_DEVICE_SYNC LITERAL1
34-
FORCE_CLOUD_SYNC LITERAL1
30+
ON LITERAL1
31+
OFF LITERAL1
32+
ON_CHANGE LITERAL1
33+
SECONDS LITERAL1
34+
MINUTES LITERAL1
35+
HOURS LITERAL1
36+
DAYS LITERAL1
37+
MOST_RECENT_WINS LITERAL1
38+
DEVICE_WINS LITERAL1
39+
CLOUD_WINS LITERAL1

src/ArduinoCloudProperty.cpp

Lines changed: 235 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,235 @@
1+
//
2+
// This file is part of ArduinoCloudThing
3+
//
4+
// Copyright 2019 ARDUINO SA (http://www.arduino.cc/)
5+
//
6+
// This software is released under the GNU General Public License version 3,
7+
// which covers the main part of ArduinoCloudThing.
8+
// The terms of this license can be found at:
9+
// https://www.gnu.org/licenses/gpl-3.0.en.html
10+
//
11+
// You can be released from the requirements of the above licenses by purchasing
12+
// a commercial license. Buying such a license is mandatory if you want to modify or
13+
// otherwise use the software for commercial activities involving the Arduino
14+
// software without disclosing the source code of your own applications. To purchase
15+
// a commercial license, send an email to [email protected].
16+
//
17+
18+
#include "ArduinoCloudProperty.h"
19+
20+
#ifdef ARDUINO_ARCH_SAMD
21+
#include <RTCZero.h>
22+
extern RTCZero rtc;
23+
#endif
24+
25+
static unsigned long getTimestamp() {
26+
#ifdef ARDUINO_ARCH_SAMD
27+
return rtc.getEpoch();
28+
#else
29+
#warning "No RTC available on this architecture - ArduinoIoTCloud will not keep track of local change timestamps ."
30+
return 0;
31+
#endif
32+
}
33+
34+
/******************************************************************************
35+
CTOR/DTOR
36+
******************************************************************************/
37+
ArduinoCloudProperty::ArduinoCloudProperty()
38+
: _name(""),
39+
_permission(Permission::Read),
40+
_update_callback_func(nullptr),
41+
_sync_callback_func(nullptr),
42+
_has_been_updated_once(false),
43+
_has_been_modified_in_callback(false),
44+
_min_delta_property(0.0f),
45+
_min_time_between_updates_millis(0),
46+
_last_updated_millis(0),
47+
_update_interval_millis(0),
48+
_last_local_change_timestamp(0),
49+
_last_cloud_change_timestamp(0),
50+
_map_data_list(nullptr) {
51+
}
52+
53+
/******************************************************************************
54+
PUBLIC MEMBER FUNCTIONS
55+
******************************************************************************/
56+
void ArduinoCloudProperty::init(String const name, Permission const permission) {
57+
_name = name;
58+
_permission = permission;
59+
}
60+
61+
ArduinoCloudProperty & ArduinoCloudProperty::onUpdate(UpdateCallbackFunc func) {
62+
_update_callback_func = func;
63+
return (*this);
64+
}
65+
66+
ArduinoCloudProperty & ArduinoCloudProperty::onSync(SyncCallbackFunc func) {
67+
_sync_callback_func = func;
68+
return (*this);
69+
}
70+
71+
ArduinoCloudProperty & ArduinoCloudProperty::publishOnChange(float const min_delta_property, unsigned long const min_time_between_updates_millis) {
72+
_update_policy = UpdatePolicy::OnChange;
73+
_min_delta_property = min_delta_property;
74+
_min_time_between_updates_millis = min_time_between_updates_millis;
75+
return (*this);
76+
}
77+
78+
ArduinoCloudProperty & ArduinoCloudProperty::publishEvery(unsigned long const seconds) {
79+
_update_policy = UpdatePolicy::TimeInterval;
80+
_update_interval_millis = (seconds * 1000);
81+
return (*this);
82+
}
83+
84+
bool ArduinoCloudProperty::shouldBeUpdated() {
85+
if (!_has_been_updated_once) {
86+
return true;
87+
}
88+
89+
if (_has_been_modified_in_callback) {
90+
_has_been_modified_in_callback = false;
91+
return true;
92+
}
93+
94+
if (_update_policy == UpdatePolicy::OnChange) {
95+
return (isDifferentFromCloud() && ((millis() - _last_updated_millis) >= (_min_time_between_updates_millis)));
96+
} else if (_update_policy == UpdatePolicy::TimeInterval) {
97+
return ((millis() - _last_updated_millis) >= _update_interval_millis);
98+
} else {
99+
return false;
100+
}
101+
}
102+
103+
void ArduinoCloudProperty::execCallbackOnChange() {
104+
if (_update_callback_func != NULL) {
105+
_update_callback_func();
106+
}
107+
if (!isDifferentFromCloud()) {
108+
_has_been_modified_in_callback = true;
109+
}
110+
}
111+
112+
void ArduinoCloudProperty::execCallbackOnSync() {
113+
if (_sync_callback_func != NULL) {
114+
_sync_callback_func(*this);
115+
}
116+
}
117+
118+
void ArduinoCloudProperty::append(CborEncoder *encoder) {
119+
appendAttributesToCloudReal(encoder);
120+
fromLocalToCloud();
121+
_has_been_updated_once = true;
122+
_last_updated_millis = millis();
123+
}
124+
125+
void ArduinoCloudProperty::appendAttributeReal(bool value, String attributeName, CborEncoder *encoder) {
126+
appendAttributeName(attributeName, [value](CborEncoder & mapEncoder) {
127+
cbor_encode_int(&mapEncoder, static_cast<int>(CborIntegerMapKey::BooleanValue));
128+
cbor_encode_boolean(&mapEncoder, value);
129+
}, encoder);
130+
}
131+
132+
void ArduinoCloudProperty::appendAttributeReal(int value, String attributeName, CborEncoder *encoder) {
133+
appendAttributeName(attributeName, [value](CborEncoder & mapEncoder) {
134+
cbor_encode_int(&mapEncoder, static_cast<int>(CborIntegerMapKey::Value));
135+
cbor_encode_int(&mapEncoder, value);
136+
}, encoder);
137+
}
138+
139+
void ArduinoCloudProperty::appendAttributeReal(float value, String attributeName, CborEncoder *encoder) {
140+
appendAttributeName(attributeName, [value](CborEncoder & mapEncoder) {
141+
cbor_encode_int(&mapEncoder, static_cast<int>(CborIntegerMapKey::Value));
142+
cbor_encode_float(&mapEncoder, value);
143+
}, encoder);
144+
}
145+
146+
void ArduinoCloudProperty::appendAttributeReal(String value, String attributeName, CborEncoder *encoder) {
147+
appendAttributeName(attributeName, [value](CborEncoder & mapEncoder) {
148+
cbor_encode_int(&mapEncoder, static_cast<int>(CborIntegerMapKey::StringValue));
149+
cbor_encode_text_stringz(&mapEncoder, value.c_str());
150+
}, encoder);
151+
}
152+
153+
void ArduinoCloudProperty::appendAttributeName(String attributeName, std::function<void (CborEncoder& mapEncoder)>appendValue, CborEncoder *encoder) {
154+
CborEncoder mapEncoder;
155+
cbor_encoder_create_map(encoder, &mapEncoder, 2);
156+
cbor_encode_int(&mapEncoder, static_cast<int>(CborIntegerMapKey::Name));
157+
String completeName = _name;
158+
if (attributeName != "") {
159+
completeName += ":" + attributeName;
160+
}
161+
cbor_encode_text_stringz(&mapEncoder, completeName.c_str());
162+
appendValue(mapEncoder);
163+
cbor_encoder_close_container(encoder, &mapEncoder);
164+
}
165+
166+
void ArduinoCloudProperty::setAttributesFromCloud(LinkedList<CborMapData *> *map_data_list) {
167+
_map_data_list = map_data_list;
168+
setAttributesFromCloud();
169+
}
170+
171+
void ArduinoCloudProperty::setAttributeReal(bool& value, String attributeName) {
172+
setAttributeReal(attributeName, [&value](CborMapData * md) {
173+
value = md->bool_val.get();
174+
});
175+
}
176+
177+
void ArduinoCloudProperty::setAttributeReal(int& value, String attributeName) {
178+
setAttributeReal(attributeName, [&value](CborMapData * md) {
179+
value = md->val.get();
180+
});
181+
}
182+
183+
void ArduinoCloudProperty::setAttributeReal(float& value, String attributeName) {
184+
setAttributeReal(attributeName, [&value](CborMapData * md) {
185+
value = md->val.get();
186+
});
187+
}
188+
189+
void ArduinoCloudProperty::setAttributeReal(String& value, String attributeName) {
190+
setAttributeReal(attributeName, [&value](CborMapData * md) {
191+
value = md->str_val.get();
192+
});
193+
}
194+
195+
void ArduinoCloudProperty::setAttributeReal(String attributeName, std::function<void (CborMapData *md)>setValue) {
196+
for (int i = 0; i < _map_data_list->size(); i++) {
197+
CborMapData *map = _map_data_list->get(i);
198+
if (map != nullptr) {
199+
String an = map->attribute_name.get();
200+
if (an == attributeName) {
201+
setValue(map);
202+
break;
203+
}
204+
}
205+
}
206+
}
207+
208+
String ArduinoCloudProperty::getAttributeName(String propertyName, char separator) {
209+
int colonPos;
210+
String attributeName = "";
211+
(colonPos = propertyName.indexOf(separator)) != -1 ? attributeName = propertyName.substring(colonPos + 1) : "";
212+
return attributeName;
213+
}
214+
215+
void ArduinoCloudProperty::updateLocalTimestamp() {
216+
if (isReadableByCloud()) {
217+
_last_local_change_timestamp = getTimestamp();
218+
}
219+
}
220+
221+
void ArduinoCloudProperty::setLastCloudChangeTimestamp(unsigned long cloudChangeEventTime) {
222+
_last_cloud_change_timestamp = cloudChangeEventTime;
223+
}
224+
225+
void ArduinoCloudProperty::setLastLocalChangeTimestamp(unsigned long localChangeTime) {
226+
_last_local_change_timestamp = localChangeTime;
227+
}
228+
229+
unsigned long ArduinoCloudProperty::getLastCloudChangeTimestamp() {
230+
return _last_cloud_change_timestamp;
231+
}
232+
233+
unsigned long ArduinoCloudProperty::getLastLocalChangeTimestamp() {
234+
return _last_local_change_timestamp;
235+
}

0 commit comments

Comments
 (0)