diff --git a/extras/test/CMakeLists.txt b/extras/test/CMakeLists.txt index 153f81b62..9ded1d88a 100644 --- a/extras/test/CMakeLists.txt +++ b/extras/test/CMakeLists.txt @@ -10,6 +10,7 @@ project(testArduinoIoTCloud) include_directories(include) include_directories(../../src/cbor) +include_directories(../../src/property) include_directories(../../src/utility/ota) include_directories(external/catch/v2.12.1/include) include_directories(external/fakeit/v2.0.5/include) @@ -51,8 +52,9 @@ set(TEST_DUT_SRCS ../../src/utility/ota/crc.cpp ../../src/utility/ota/OTALogic.cpp + ../../src/property/Property.cpp + ../../src/property/PropertyContainer.cpp ../../src/cbor/ArduinoCloudThing.cpp - ../../src/cbor/ArduinoCloudProperty.cpp ../../src/cbor/lib/tinycbor/src/cborencoder.c ../../src/cbor/lib/tinycbor/src/cborencoder_close_container_checked.c ../../src/cbor/lib/tinycbor/src/cborerrorstrings.c diff --git a/extras/test/src/test_addPropertyReal.cpp b/extras/test/src/test_addPropertyReal.cpp index 6d60f8982..573f18802 100644 --- a/extras/test/src/test_addPropertyReal.cpp +++ b/extras/test/src/test_addPropertyReal.cpp @@ -8,7 +8,12 @@ #include -#include +#include + +#include +#include +#include +#include /************************************************************************************** TEST CODE @@ -16,13 +21,12 @@ SCENARIO("The same arduino cloud properties are added multiple times", "[ArduinoCloudThing::addPropertyReal]") { WHEN("The same bool property is added multiple times") { - ArduinoCloudThing thing; - thing.begin(); + PropertyContainer property_container; CloudBool bool_property = false; - ArduinoCloudProperty * bool_property_ptr_1 = &thing.addPropertyReal(bool_property, "bool_property", Permission::ReadWrite); - ArduinoCloudProperty * bool_property_ptr_2 = &thing.addPropertyReal(bool_property, "bool_property", Permission::ReadWrite); + Property * bool_property_ptr_1 = &property_container.addPropertyReal(bool_property, "bool_property", Permission::ReadWrite); + Property * bool_property_ptr_2 = &property_container.addPropertyReal(bool_property, "bool_property", Permission::ReadWrite); THEN("No new property is added and the first added property is returned instead of a new one") { REQUIRE(bool_property_ptr_1 == bool_property_ptr_2); } @@ -31,13 +35,12 @@ SCENARIO("The same arduino cloud properties are added multiple times", "[Arduino /**************************************************************************************/ WHEN("the same int property is added multiple times") { - ArduinoCloudThing thing; - thing.begin(); + PropertyContainer property_container; CloudInt int_property = 1; - ArduinoCloudProperty * int_property_ptr_1 = &thing.addPropertyReal(int_property, "int_property", Permission::ReadWrite); - ArduinoCloudProperty * int_property_ptr_2 = &thing.addPropertyReal(int_property, "int_property", Permission::ReadWrite); + Property * int_property_ptr_1 = &property_container.addPropertyReal(int_property, "int_property", Permission::ReadWrite); + Property * int_property_ptr_2 = &property_container.addPropertyReal(int_property, "int_property", Permission::ReadWrite); THEN("No new property is added and the first added property is returned instead of a new one") { REQUIRE(int_property_ptr_1 == int_property_ptr_2); @@ -47,13 +50,12 @@ SCENARIO("The same arduino cloud properties are added multiple times", "[Arduino /**************************************************************************************/ WHEN("the same float property is added multiple times") { - ArduinoCloudThing thing; - thing.begin(); + PropertyContainer property_container; CloudFloat float_property = 1.0f; - ArduinoCloudProperty * float_property_ptr_1 = &thing.addPropertyReal(float_property, "float_property", Permission::ReadWrite); - ArduinoCloudProperty * float_property_ptr_2 = &thing.addPropertyReal(float_property, "float_property", Permission::ReadWrite); + Property * float_property_ptr_1 = &property_container.addPropertyReal(float_property, "float_property", Permission::ReadWrite); + Property * float_property_ptr_2 = &property_container.addPropertyReal(float_property, "float_property", Permission::ReadWrite); THEN("No new property is added and the first added property is returned instead of a new one") { REQUIRE(float_property_ptr_1 == float_property_ptr_2); @@ -63,13 +65,12 @@ SCENARIO("The same arduino cloud properties are added multiple times", "[Arduino /**************************************************************************************/ WHEN("the same String property is added multiple times") { - ArduinoCloudThing thing; - thing.begin(); + PropertyContainer property_container; CloudString str_property; - ArduinoCloudProperty * str_property_ptr_1 = &thing.addPropertyReal(str_property, "str_property", Permission::ReadWrite); - ArduinoCloudProperty * str_property_ptr_2 = &thing.addPropertyReal(str_property, "str_property", Permission::ReadWrite); + Property * str_property_ptr_1 = &property_container.addPropertyReal(str_property, "str_property", Permission::ReadWrite); + Property * str_property_ptr_2 = &property_container.addPropertyReal(str_property, "str_property", Permission::ReadWrite); THEN("No new property is added and the first added property is returned instead of a new one") { REQUIRE(str_property_ptr_1 == str_property_ptr_2); diff --git a/extras/test/src/test_callback.cpp b/extras/test/src/test_callback.cpp index 447b73d61..2e8ce2557 100644 --- a/extras/test/src/test_callback.cpp +++ b/extras/test/src/test_callback.cpp @@ -10,6 +10,7 @@ #include #include +#include #include "types/CloudWrapperBool.h" /************************************************************************************** @@ -39,11 +40,12 @@ SCENARIO("A callback is registered via 'onUpdate' to be called on property chang /************************************************************************************/ GIVEN("CloudProtocol::V2") { + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); CloudInt test = 10; - thing.addPropertyReal(test, "test", Permission::ReadWrite).onUpdate(externalCallbackV2); + property_container.addPropertyReal(test, "test", Permission::ReadWrite).onUpdate(externalCallbackV2); /* [{0: "test", 2: 7}] = 81 A2 00 64 74 65 73 74 02 07 */ uint8_t const payload[] = {0x81, 0xA2, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x02, 0x07}; @@ -68,11 +70,12 @@ void switch_callback() { SCENARIO("A (boolean) property is manipulated in the callback to its origin state", "[ArduinoCloudThing::decode]") { GIVEN("CloudProtocol::V2") { + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); cbor::encode(thing); - thing.addPropertyReal(switch_turned_on, "switch_turned_on", Permission::ReadWrite).onUpdate(switch_callback); + property_container.addPropertyReal(switch_turned_on, "switch_turned_on", Permission::ReadWrite).onUpdate(switch_callback); /* [{0: "switch_turned_on", 4: true}] = 81 A2 00 70 73 77 69 74 63 68 5F 74 75 72 6E 65 64 5F 6F 6E 04 F5 */ uint8_t const payload[] = {0x81, 0xA2, 0x00, 0x70, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x5F, 0x74, 0x75, 0x72, 0x6E, 0x65, 0x64, 0x5F, 0x6F, 0x6E, 0x04, 0xF5}; @@ -98,7 +101,7 @@ SCENARIO("A (boolean) property is manipulated in the callback to its origin stat static bool sync_callback_called = false; static bool change_callback_called = false; -void auto_sync_callback(ArduinoCloudProperty& property) { +void auto_sync_callback(Property& property) { MOST_RECENT_WINS(property); sync_callback_called = true; } @@ -113,10 +116,11 @@ SCENARIO("After a connection/reconnection an incoming cbor payload is processed sync_callback_called = false; change_callback_called = false; + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); - thing.addPropertyReal(test, "test", Permission::ReadWrite).onUpdate(change_callback).onSync(auto_sync_callback); + property_container.addPropertyReal(test, "test", Permission::ReadWrite).onUpdate(change_callback).onSync(auto_sync_callback); test.setLastLocalChangeTimestamp(1550138809); @@ -140,10 +144,11 @@ SCENARIO("After a connection/reconnection an incoming cbor payload is processed sync_callback_called = false; change_callback_called = false; + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); - thing.addPropertyReal(test, "test", Permission::ReadWrite).onUpdate(change_callback).onSync(auto_sync_callback); + property_container.addPropertyReal(test, "test", Permission::ReadWrite).onUpdate(change_callback).onSync(auto_sync_callback); test = false; test.setLastLocalChangeTimestamp(1550138811); @@ -162,16 +167,17 @@ SCENARIO("After a connection/reconnection an incoming cbor payload is processed SCENARIO("Primitive property: After a connection/reconnection an incoming cbor payload is processed and the synchronization callback is executed. The sync callback applies the AUTO_SYNC policy (the most recent value between the local one and the cloud one is finally assigned to the property). The onUpdate function is called if the cloud value is the most recent one. In this scenario the most updated value is the cloud one.") { GIVEN("CloudProtocol::V2") { bool test = true; - std::unique_ptr p(new CloudWrapperBool(test)); + std::unique_ptr p(new CloudWrapperBool(test)); sync_callback_called = false; change_callback_called = false; + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); - thing.addPropertyReal(*p, "test", Permission::ReadWrite).onUpdate(change_callback).onSync(auto_sync_callback); + property_container.addPropertyReal(*p, "test", Permission::ReadWrite).onUpdate(change_callback).onSync(auto_sync_callback); test = false; - thing.updateTimestampOnLocallyChangedProperties(); + property_container.updateTimestampOnLocallyChangedProperties(); //There is no RTC on test execution environment so we force the local timestamp p->setLastLocalChangeTimestamp(1550138809); @@ -192,16 +198,17 @@ SCENARIO("Primitive property: After a connection/reconnection an incoming cbor p SCENARIO("Primitive property: After a connection/reconnection an incoming cbor payload is processed and the synchronization callback is executed. The sync callback apply the AUTO_SYNC policy (the most recent value between the local one and the cloud one is finally assigned to the property). The onUpdate function is called if the cloud value is the most recent one. In this scenario the most updated value is the local one.") { GIVEN("CloudProtocol::V2") { bool test = true; - std::unique_ptr p(new CloudWrapperBool(test)); + std::unique_ptr p(new CloudWrapperBool(test)); sync_callback_called = false; change_callback_called = false; + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); - thing.addPropertyReal(*p, "test", Permission::ReadWrite).onUpdate(change_callback).onSync(auto_sync_callback); + property_container.addPropertyReal(*p, "test", Permission::ReadWrite).onUpdate(change_callback).onSync(auto_sync_callback); test = false; - thing.updateTimestampOnLocallyChangedProperties(); + property_container.updateTimestampOnLocallyChangedProperties(); //There is no RTC on test execution environment so we force the local timestamp p->setLastLocalChangeTimestamp(1550138811); @@ -223,10 +230,11 @@ SCENARIO("Object property: After a connection/reconnection an incoming cbor payl sync_callback_called = false; change_callback_called = false; + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); - thing.addPropertyReal(location_test, "test", Permission::ReadWrite).onUpdate(change_callback).onSync(auto_sync_callback); + property_container.addPropertyReal(location_test, "test", Permission::ReadWrite).onUpdate(change_callback).onSync(auto_sync_callback); location_test.setLastLocalChangeTimestamp(1550138809); /* [{-3: 1550138810.00, 0: "test:lat", 3: 2},{0: "test:lon", 3: 3}] = 82 A3 22 FB 41 D7 19 4F 6E 80 00 00 00 68 74 65 73 74 3A 6C 61 74 02 02 A2 00 68 74 65 73 74 3A 6C 6F 6E 02 03*/ @@ -254,10 +262,11 @@ SCENARIO("Object property: After a connection/reconnection an incoming cbor payl sync_callback_called = false; change_callback_called = false; + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); - thing.addPropertyReal(location_test, "test", Permission::ReadWrite).onUpdate(change_callback).onSync(auto_sync_callback); + property_container.addPropertyReal(location_test, "test", Permission::ReadWrite).onUpdate(change_callback).onSync(auto_sync_callback); location_test.setLastLocalChangeTimestamp(1550138811); /* [{-3: 1550138810.00, 0: "test:lat", 3: 2},{0: "test:lon", 3: 3}] = 82 A3 22 FB 41 D7 19 4F 6E 80 00 00 00 68 74 65 73 74 3A 6C 61 74 02 02 A2 00 68 74 65 73 74 3A 6C 6F 6E 02 03*/ @@ -279,7 +288,7 @@ SCENARIO("Object property: After a connection/reconnection an incoming cbor payl /**************************************************************************************/ -void force_device_sync_callback(ArduinoCloudProperty& property) { +void force_device_sync_callback(Property& property) { DEVICE_WINS(property); sync_callback_called = true; } @@ -291,10 +300,11 @@ SCENARIO("After a connection/reconnection an incoming cbor payload is processed sync_callback_called = false; change_callback_called = false; + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); - thing.addPropertyReal(test, "test", Permission::ReadWrite).onUpdate(change_callback).onSync(force_device_sync_callback); + property_container.addPropertyReal(test, "test", Permission::ReadWrite).onUpdate(change_callback).onSync(force_device_sync_callback); /* [{-3: 1550138810.00, 0: "test", 4: true}] = 81 A3 22 FB 41 D7 19 4F 6E 80 00 00 00 64 74 65 73 74 04 F5 */ uint8_t const payload[] = {0x81, 0xA3, 0x22, 0xFB, 0x41, 0xD7, 0x19, 0x4F, 0x6E, 0x80, 0x00, 0x00, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x04, 0xF5}; @@ -311,7 +321,7 @@ SCENARIO("After a connection/reconnection an incoming cbor payload is processed /**************************************************************************************/ -void force_cloud_sync_callback(ArduinoCloudProperty& property) { +void force_cloud_sync_callback(Property& property) { CLOUD_WINS(property); sync_callback_called = true; } @@ -323,10 +333,11 @@ SCENARIO("After a connection/reconnection an incoming cbor payload is processed sync_callback_called = false; change_callback_called = false; + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); - thing.addPropertyReal(test, "test", Permission::ReadWrite).onUpdate(change_callback).onSync(force_cloud_sync_callback); + property_container.addPropertyReal(test, "test", Permission::ReadWrite).onUpdate(change_callback).onSync(force_cloud_sync_callback); /* [{-3: 1550138810.00, 0: "test", 4: true}] = 81 A3 22 FB 41 D7 19 4F 6E 80 00 00 00 64 74 65 73 74 04 F5 */ uint8_t const payload[] = {0x81, 0xA3, 0x22, 0xFB, 0x41, 0xD7, 0x19, 0x4F, 0x6E, 0x80, 0x00, 0x00, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x04, 0xF5}; @@ -349,10 +360,11 @@ SCENARIO("After a connection/reconnection an incoming cbor payload is processed. sync_callback_called = false; change_callback_called = false; + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); - thing.addPropertyReal(test, "test", Permission::ReadWrite).onUpdate(change_callback); + property_container.addPropertyReal(test, "test", Permission::ReadWrite).onUpdate(change_callback); /* [{-3: 1550138810.00, 0: "test", 4: true}] = 81 A3 22 FB 41 D7 19 4F 6E 80 00 00 00 64 74 65 73 74 04 F5 */ uint8_t const payload[] = {0x81, 0xA3, 0x22, 0xFB, 0x41, 0xD7, 0x19, 0x4F, 0x6E, 0x80, 0x00, 0x00, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x04, 0xF5}; diff --git a/extras/test/src/test_decode.cpp b/extras/test/src/test_decode.cpp index 43c66b4cc..a3e2cc2ad 100644 --- a/extras/test/src/test_decode.cpp +++ b/extras/test/src/test_decode.cpp @@ -35,11 +35,12 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") WHEN("A boolean property is changed via CBOR message") { GIVEN("CloudProtocol::V2") { + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); CloudBool test = true; - thing.addPropertyReal(test, "test", Permission::ReadWrite); + property_container.addPropertyReal(test, "test", Permission::ReadWrite); /* [{0: "test", 4: false}] = 81 A2 00 64 74 65 73 74 04 F4 */ uint8_t const payload[] = {0x81, 0xA2, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x04, 0xF4}; @@ -55,12 +56,13 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") WHEN("A boolean property is changed via CBOR message - light payload") { /*An integer identifier has been encoded instead of the name of the property in order to have a shorter payload*/ GIVEN("CloudProtocol::V2") { + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); CloudBool test = true; /*The property is added with identifier 1 that will be used instead of the string "test" as property identifier*/ - thing.addPropertyReal(test, "test", Permission::ReadWrite, 1); + property_container.addPropertyReal(test, "test", Permission::ReadWrite, 1); /* [{0: 1, 4: false}] = 81 A2 00 01 04 F4 */ uint8_t const payload[] = {0x81, 0xA2, 0x00, 0x01, 0x04, 0xF4}; @@ -75,11 +77,12 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") WHEN("A int property is changed via CBOR message") { GIVEN("CloudProtocol::V2") { + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); CloudInt test = 0; - thing.addPropertyReal(test, "test", Permission::ReadWrite); + property_container.addPropertyReal(test, "test", Permission::ReadWrite); /* [{0: "test", 2: 7}] = 81 A2 00 64 74 65 73 74 02 07 */ uint8_t const payload[] = {0x81, 0xA2, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x02, 0x07}; @@ -89,11 +92,12 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") REQUIRE(test == 7); } GIVEN("CloudProtocol::V2") { + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); CloudInt test = 0; - thing.addPropertyReal(test, "test", Permission::ReadWrite); + property_container.addPropertyReal(test, "test", Permission::ReadWrite); /* [{0: "test", 2: -7}] = 81 A2 00 64 74 65 73 74 02 26 */ uint8_t const payload[] = {0x81, 0xA2, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x02, 0x26}; @@ -108,11 +112,12 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") WHEN("A float property is changed via CBOR message") { GIVEN("CloudProtocol::V2") { + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); CloudFloat test = 0.0f; - thing.addPropertyReal(test, "test", Permission::ReadWrite); + property_container.addPropertyReal(test, "test", Permission::ReadWrite); /* [{0: "test", 2: 3.1459}] = 81 A2 00 64 74 65 73 74 02 FB 40 09 2A CD 9E 83 E4 26 */ uint8_t const payload[] = {0x81, 0xA2, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x02, 0xFB, 0x40, 0x09, 0x2A, 0xCD, 0x9E, 0x83, 0xE4, 0x26}; @@ -127,12 +132,13 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") WHEN("A String property is changed via CBOR message") { GIVEN("CloudProtocol::V2") { + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); CloudString str_test; str_test = "test"; - thing.addPropertyReal(str_test, "test", Permission::ReadWrite); + property_container.addPropertyReal(str_test, "test", Permission::ReadWrite); /* [{0: "test", 3: "testtt"}] = 81 A2 00 64 74 65 73 74 03 66 74 65 73 74 74 74 */ uint8_t const payload[] = {0x81, 0xA2, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x03, 0x66, 0x74, 0x65, 0x73, 0x74, 0x74, 0x74}; @@ -146,11 +152,12 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") WHEN("A Location property is changed via CBOR message") { GIVEN("CloudProtocol::V2") { + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); CloudLocation location_test = CloudLocation(0, 1); - thing.addPropertyReal(location_test, "test", Permission::ReadWrite); + property_container.addPropertyReal(location_test, "test", Permission::ReadWrite); /* [{0: "test:lat", 3: 2},{0: "test:lon", 3: 3}] = 82 A2 00 68 74 65 73 74 3A 6C 61 74 02 02 A2 00 68 74 65 73 74 3A 6C 6F 6E 02 03*/ uint8_t const payload[] = { 0x82, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x6C, 0x61, 0x74, 0x02, 0x02, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x6C, 0x6F, 0x6E, 0x02, 0x03 }; @@ -166,12 +173,13 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") WHEN("A Color property is changed via CBOR message") { GIVEN("CloudProtocol::V2") { + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); CloudColor color_test = CloudColor(0.0, 0.0, 0.0); - thing.addPropertyReal(color_test, "test", Permission::ReadWrite); + property_container.addPropertyReal(color_test, "test", Permission::ReadWrite); /* [{0: "test:hue", 2: 2.0},{0: "test:sat", 2: 2.0},{0: "test:bri", 2: 2.0}] = 83 A2 00 68 74 65 73 74 3A 68 75 65 02 FA 40 00 00 00 A2 00 68 74 65 73 74 3A 73 61 74 02 FA 40 00 00 00 A2 00 68 74 65 73 74 3A 62 72 69 02 FA 40 00 00 00 */ uint8_t const payload[] = {0x83, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x68, 0x75, 0x65, 0x02, 0xFA, 0x40, 0x00, 0x00, 0x00, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x73, 0x61, 0x74, 0x02, 0xFA, 0x40, 0x00, 0x00, 0x00, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x62, 0x72, 0x69, 0x02, 0xFA, 0x40, 0x00, 0x00, 0x00 }; @@ -192,13 +200,14 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") WHEN("A Color property is changed via CBOR message - light payload") { /*An integer identifier has been encoded instead of the name of the property in order to have a shorter payload*/ GIVEN("CloudProtocol::V2") { + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); CloudColor color_test = CloudColor(0.0, 0.0, 0.0); /*The property is added with identifier 1 that will be used instead of the string "test" as property identifier*/ - thing.addPropertyReal(color_test, "test", Permission::ReadWrite, 1); + property_container.addPropertyReal(color_test, "test", Permission::ReadWrite, 1); /* [{0: 257, 2: 2.0},{0: 513, 2: 2.0},{0: 769, 2: 2.0}] = 83 A2 00 19 01 01 02 FA 40 00 00 00 A2 00 19 02 01 02 FA 40 00 00 00 A2 00 19 03 01 02 FA 40 00 00 00 */ uint8_t const payload[] = {0x83, 0xA2, 0x00, 0x19, 0x01, 0x01, 0x02, 0xFA, 0x40, 0x00, 0x00, 0x00, 0xA2, 0x00, 0x19, 0x02, 0x01, 0x02, 0xFA, 0x40, 0x00, 0x00, 0x00, 0xA2, 0x00, 0x19, 0x03, 0x01, 0x02, 0xFA, 0x40, 0x00, 0x00, 0x00 }; @@ -218,12 +227,13 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") WHEN("A ColoredLight property is changed via CBOR message") { GIVEN("CloudProtocol::V2") { + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); CloudColoredLight color_test = CloudColoredLight(false, 0.0, 0.0, 0.0); - thing.addPropertyReal(color_test, "test", Permission::ReadWrite); + property_container.addPropertyReal(color_test, "test", Permission::ReadWrite); /* [{0: "test:swi", 4: true},{0: "test:hue", 2: 2.0},{0: "test:sat", 2: 2.0},{0: "test:bri", 2: 2.0}] = 83 A2 00 68 74 65 73 74 3A 73 77 69 04 F5 //A2 00 68 74 65 73 74 3A 68 75 65 02 FA 40 00 00 00 A2 00 68 74 65 73 74 3A 73 61 74 02 FA 40 00 00 00 A2 00 68 74 65 73 74 3A 62 72 69 02 FA 40 00 00 00 */ uint8_t const payload[] = {0x84, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x73, 0x77, 0x69, 0x04, 0xF5, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x68, 0x75, 0x65, 0x02, 0xFA, 0x40, 0x00, 0x00, 0x00, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x73, 0x61, 0x74, 0x02, 0xFA, 0x40, 0x00, 0x00, 0x00, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x62, 0x72, 0x69, 0x02, 0xFA, 0x40, 0x00, 0x00, 0x00 }; @@ -244,13 +254,14 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") WHEN("A Television property is changed via CBOR message") { GIVEN("CloudProtocol::V2") { + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); CloudTelevision tv_test = CloudTelevision(false, 0, false, PlaybackCommands::Stop, InputValue::AUX1, 0); - thing.addPropertyReal(tv_test, "test", Permission::ReadWrite); + property_container.addPropertyReal(tv_test, "test", Permission::ReadWrite); /* [{0: "test:swi", 4: true},{0: "test:vol", 2: 50},{0: "test:mut", 2: false},{0: "test:pbc", 2: 3},{0: "test:inp", 2: 55},{0: "test:cha", 2: 7}] = 9F A2 00 68 74 65 73 74 3A 73 77 69 04 F5 A2 00 68 74 65 73 74 3A 76 6F 6C 02 18 32 A2 00 68 74 65 73 74 3A 6D 75 74 04 F4 A2 00 68 74 65 73 74 3A 70 62 63 02 03 A2 00 68 74 65 73 74 3A 69 6E 70 02 18 37 A2 00 68 74 65 73 74 3A 63 68 61 02 07 FF */ uint8_t const payload[] = {0x9F, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x73, 0x77, 0x69, 0x04, 0xF5, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x76, 0x6F, 0x6C, 0x02, 0x18, 0x32, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x6D, 0x75, 0x74, 0x04, 0xF4, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x70, 0x62, 0x63, 0x02, 0x03, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x69, 0x6E, 0x70, 0x02, 0x18, 0x37, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x63, 0x68, 0x61, 0x02, 0x07, 0xFF}; @@ -273,12 +284,13 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") WHEN("A DimmedLight property is changed via CBOR message") { GIVEN("CloudProtocol::V2") { + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); CloudDimmedLight light_test = CloudDimmedLight(false, 0.0); - thing.addPropertyReal(light_test, "test", Permission::ReadWrite); + property_container.addPropertyReal(light_test, "test", Permission::ReadWrite); /* [{0: "test:swi", 4: true},{0: "test:bri", 2: 2.0}] = 83 A2 00 68 74 65 73 74 3A 73 77 69 04 F5 //A2 00 68 74 65 73 74 3A 62 72 69 02 FA 40 00 00 00 */ uint8_t const payload[] = {0x82, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x73, 0x77, 0x69, 0x04, 0xF5, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x62, 0x72, 0x69, 0x02, 0xFA, 0x40, 0x00, 0x00, 0x00}; @@ -297,13 +309,14 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") WHEN("A Light property is changed via CBOR message") { GIVEN("CloudProtocol::V2") { + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); CloudLight light_test; light_test = false; - thing.addPropertyReal(light_test, "test", Permission::ReadWrite); + property_container.addPropertyReal(light_test, "test", Permission::ReadWrite); /* [{0: "test", 4: true}] = 81 A2 00 64 74 65 73 74 04 F5 */ uint8_t const payload[] = {0x81, 0xA2, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x04, 0xF5}; @@ -317,13 +330,14 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") WHEN("A ContactSensor property is changed via CBOR message") { GIVEN("CloudProtocol::V2") { + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); CloudContactSensor contact_test; contact_test = false; - thing.addPropertyReal(contact_test, "test", Permission::ReadWrite); + property_container.addPropertyReal(contact_test, "test", Permission::ReadWrite); /* [{0: "test", 4: true}] = 81 A2 00 64 74 65 73 74 04 F5 */ uint8_t const payload[] = {0x81, 0xA2, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x04, 0xF5}; @@ -337,13 +351,14 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") WHEN("A MotionSensor property is changed via CBOR message") { GIVEN("CloudProtocol::V2") { + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); CloudMotionSensor motion_test; motion_test = false; - thing.addPropertyReal(motion_test, "test", Permission::ReadWrite); + property_container.addPropertyReal(motion_test, "test", Permission::ReadWrite); /* [{0: "test", 4: true}] = 81 A2 00 64 74 65 73 74 04 F5 */ uint8_t const payload[] = {0x81, 0xA2, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x04, 0xF5}; @@ -357,13 +372,14 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") WHEN("A SmartPlug property is changed via CBOR message") { GIVEN("CloudProtocol::V2") { + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); CloudSmartPlug plug_test; plug_test = false; - thing.addPropertyReal(plug_test, "test", Permission::ReadWrite); + property_container.addPropertyReal(plug_test, "test", Permission::ReadWrite); /* [{0: "test", 4: true}] = 81 A2 00 64 74 65 73 74 04 F5 */ uint8_t const payload[] = {0x81, 0xA2, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x04, 0xF5}; @@ -377,13 +393,14 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") WHEN("A Switch property is changed via CBOR message") { GIVEN("CloudProtocol::V2") { + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); CloudSwitch switch_test; switch_test = false; - thing.addPropertyReal(switch_test, "test", Permission::ReadWrite); + property_container.addPropertyReal(switch_test, "test", Permission::ReadWrite); /* [{0: "test", 4: true}] = 81 A2 00 64 74 65 73 74 04 F5 */ uint8_t const payload[] = {0x81, 0xA2, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x04, 0xF5}; @@ -397,12 +414,13 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") WHEN("A Temperature property is changed via CBOR message") { GIVEN("CloudProtocol::V2") { + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); CloudTemperature test; test = 0.0f; - thing.addPropertyReal(test, "test", Permission::ReadWrite); + property_container.addPropertyReal(test, "test", Permission::ReadWrite); /* [{0: "test", 2: 3.1459}] = 81 A2 00 64 74 65 73 74 02 FB 40 09 2A CD 9E 83 E4 26 */ uint8_t const payload[] = {0x81, 0xA2, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x02, 0xFB, 0x40, 0x09, 0x2A, 0xCD, 0x9E, 0x83, 0xE4, 0x26}; @@ -418,8 +436,9 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") WHEN("Multiple properties is changed via CBOR message") { GIVEN("CloudProtocol::V2") { WHEN("Multiple properties of different type are changed via CBOR message") { - ArduinoCloudThing thing; - thing.begin(); + PropertyContainer property_container; + ArduinoCloudThing thing; + thing.begin(&property_container); CloudBool bool_test = false; CloudInt int_test = 1; @@ -427,10 +446,10 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") CloudString str_test; str_test = ("str_test"); - thing.addPropertyReal(bool_test, "bool_test", Permission::ReadWrite); - thing.addPropertyReal(int_test, "int_test", Permission::ReadWrite); - thing.addPropertyReal(float_test, "float_test", Permission::ReadWrite); - thing.addPropertyReal(str_test, "str_test", Permission::ReadWrite); + property_container.addPropertyReal(bool_test, "bool_test", Permission::ReadWrite); + property_container.addPropertyReal(int_test, "int_test", Permission::ReadWrite); + property_container.addPropertyReal(float_test, "float_test", Permission::ReadWrite); + property_container.addPropertyReal(str_test, "str_test", Permission::ReadWrite); /* [{0: "bool_test", 4: true}, {0: "int_test", 2: 10}, {0: "float_test", 2: 20.0}, {0: "str_test", 3: "hello arduino"}] = 84 A2 00 69 62 6F 6F 6C 5F 74 65 73 74 04 F5 A2 00 68 69 6E 74 5F 74 65 73 74 02 0A A2 00 6A 66 6C 6F 61 74 5F 74 65 73 74 02 F9 4D 00 A2 00 68 73 74 72 5F 74 65 73 74 03 6D 68 65 6C 6C 6F 20 61 72 64 75 69 6E 6F @@ -447,8 +466,9 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") /********************************************************************************/ WHEN("Multiple properties of different type are synchronized via CBOR message. FORCE_CLOUD_SYNC is passed as synchronization function and as a consequence values contained in the incoming message are stored in the properties") { - ArduinoCloudThing thing; - thing.begin(); + PropertyContainer property_container; + ArduinoCloudThing thing; + thing.begin(&property_container); CloudBool bool_test = false; CloudInt int_test = 1; @@ -456,10 +476,10 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") CloudString str_test; str_test = ("str_test"); - thing.addPropertyReal(bool_test, "bool_test", Permission::ReadWrite).onSync(CLOUD_WINS); - thing.addPropertyReal(int_test, "int_test", Permission::ReadWrite).onSync(CLOUD_WINS); - thing.addPropertyReal(float_test, "float_test", Permission::ReadWrite).onSync(CLOUD_WINS); - thing.addPropertyReal(str_test, "str_test", Permission::ReadWrite).onSync(CLOUD_WINS); + property_container.addPropertyReal(bool_test, "bool_test", Permission::ReadWrite).onSync(CLOUD_WINS); + property_container.addPropertyReal(int_test, "int_test", Permission::ReadWrite).onSync(CLOUD_WINS); + property_container.addPropertyReal(float_test, "float_test", Permission::ReadWrite).onSync(CLOUD_WINS); + property_container.addPropertyReal(str_test, "str_test", Permission::ReadWrite).onSync(CLOUD_WINS); /* [{0: "bool_test", 4: true}, {0: "int_test", 2: 10}, {0: "float_test", 2: 20.0}, {0: "str_test", 3: "hello arduino"}] = 84 A2 00 69 62 6F 6F 6C 5F 74 65 73 74 04 F5 A2 00 68 69 6E 74 5F 74 65 73 74 02 0A A2 00 6A 66 6C 6F 61 74 5F 74 65 73 74 02 F9 4D 00 A2 00 68 73 74 72 5F 74 65 73 74 03 6D 68 65 6C 6C 6F 20 61 72 64 75 69 6E 6F @@ -476,8 +496,9 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") /********************************************************************************/ WHEN("Multiple primitive properties of different type are synchronized via CBOR message. FORCE_CLOUD_SYNC is passed as synchronization function and as a consequence values contained in the incoming message are stored in the properties") { - ArduinoCloudThing thing; - thing.begin(); + PropertyContainer property_container; + ArduinoCloudThing thing; + thing.begin(&property_container); int int_test = 1; bool bool_test = false; @@ -485,17 +506,17 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") String str_test; str_test = "str_test"; - std::unique_ptr i(new CloudWrapperInt(int_test)); - std::unique_ptr b(new CloudWrapperBool(bool_test)); - std::unique_ptr f(new CloudWrapperFloat(float_test)); - std::unique_ptr s(new CloudWrapperString(str_test)); + std::unique_ptr i(new CloudWrapperInt(int_test)); + std::unique_ptr b(new CloudWrapperBool(bool_test)); + std::unique_ptr f(new CloudWrapperFloat(float_test)); + std::unique_ptr s(new CloudWrapperString(str_test)); - thing.addPropertyReal(*b, "bool_test", Permission::ReadWrite).onSync(CLOUD_WINS); - thing.addPropertyReal(*i, "int_test", Permission::ReadWrite).onSync(CLOUD_WINS); - thing.addPropertyReal(*f, "float_test", Permission::ReadWrite).onSync(CLOUD_WINS); - thing.addPropertyReal(*s, "str_test", Permission::ReadWrite).onSync(CLOUD_WINS); + property_container.addPropertyReal(*b, "bool_test", Permission::ReadWrite).onSync(CLOUD_WINS); + property_container.addPropertyReal(*i, "int_test", Permission::ReadWrite).onSync(CLOUD_WINS); + property_container.addPropertyReal(*f, "float_test", Permission::ReadWrite).onSync(CLOUD_WINS); + property_container.addPropertyReal(*s, "str_test", Permission::ReadWrite).onSync(CLOUD_WINS); - thing.updateTimestampOnLocallyChangedProperties(); + property_container.updateTimestampOnLocallyChangedProperties(); /* [{0: "bool_test", 4: true}, {0: "int_test", 2: 10}, {0: "float_test", 2: 20.0}, {0: "str_test", 3: "hello arduino"}] = 84 A2 00 69 62 6F 6F 6C 5F 74 65 73 74 04 F5 A2 00 68 69 6E 74 5F 74 65 73 74 02 0A A2 00 6A 66 6C 6F 61 74 5F 74 65 73 74 02 F9 4D 00 A2 00 68 73 74 72 5F 74 65 73 74 03 6D 68 65 6C 6C 6F 20 61 72 64 75 69 6E 6F @@ -512,18 +533,19 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") /********************************************************************************/ WHEN("Multiple String properties are changed via CBOR message") { - ArduinoCloudThing thing; - thing.begin(); + PropertyContainer property_container; + ArduinoCloudThing thing; + thing.begin(&property_container); CloudString str_1("hello"), str_2("arduino"), str_3("cloud"), str_4("test"); - thing.addPropertyReal(str_1, "str_1", Permission::ReadWrite); - thing.addPropertyReal(str_2, "str_2", Permission::ReadWrite); - thing.addPropertyReal(str_3, "str_3", Permission::ReadWrite); - thing.addPropertyReal(str_4, "str_4", Permission::ReadWrite); + property_container.addPropertyReal(str_1, "str_1", Permission::ReadWrite); + property_container.addPropertyReal(str_2, "str_2", Permission::ReadWrite); + property_container.addPropertyReal(str_3, "str_3", Permission::ReadWrite); + property_container.addPropertyReal(str_4, "str_4", Permission::ReadWrite); /* [{0: "str_1", 3: "I'd like"}, {0: "str_2", 3: "a"}, {0: "str_3", 3: "cup"}, {0: "str_4", 3: "of coffee"}] = 84 A2 00 65 73 74 72 5F 31 03 68 49 27 64 20 6C 69 6B 65 A2 00 65 73 74 72 5F 32 03 61 61 A2 00 65 73 74 72 5F 33 03 63 63 75 70 A2 00 65 73 74 72 5F 34 03 69 6F 66 20 63 6F 66 66 65 65 @@ -543,11 +565,12 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") WHEN("A payload containing a CBOR base name is parsed") { GIVEN("CloudProtocol::V2") { + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); CloudString str = "hello"; - thing.addPropertyReal(str, "test", Permission::ReadWrite); + property_container.addPropertyReal(str, "test", Permission::ReadWrite); /* [{-2: "some-test-base-name", 0: "test", 3: "test"}] = 81 A3 21 73 73 6F 6D 65 2D 74 65 73 74 2D 62 61 73 65 2D 6E 61 6D 65 00 64 74 65 73 74 03 64 74 65 73 74 */ uint8_t const payload[] = {0x81, 0xA3, 0x21, 0x73, 0x73, 0x6F, 0x6D, 0x65, 0x2D, 0x74, 0x65, 0x73, 0x74, 0x2D, 0x62, 0x61, 0x73, 0x65, 0x2D, 0x6E, 0x61, 0x6D, 0x65, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x03, 0x64, 0x74, 0x65, 0x73, 0x74}; @@ -561,11 +584,12 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") WHEN("A payload containing a CBOR base time is parsed") { GIVEN("CloudProtocol::V2") { + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); CloudInt test = 0; - thing.addPropertyReal(test, "test", Permission::ReadWrite); + property_container.addPropertyReal(test, "test", Permission::ReadWrite); /* [{-3: 123.456, 0: "test", 2: 1}] = 81 A3 22 FB 40 5E DD 2F 1A 9F BE 77 00 64 74 65 73 74 02 01 */ uint8_t const payload[] = {0x81, 0xA3, 0x22, 0xFB, 0x40, 0x5E, 0xDD, 0x2F, 0x1A, 0x9F, 0xBE, 0x77, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x02, 0x01}; @@ -579,11 +603,12 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") WHEN("A payload containing a CBOR time is parsed") { GIVEN("CloudProtocol::V2") { + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); CloudInt test = 0; - thing.addPropertyReal(test, "test", Permission::ReadWrite); + property_container.addPropertyReal(test, "test", Permission::ReadWrite); /* [{6: 123.456, 0: "test", 2: 1}] = 81 A3 06 FB 40 5E DD 2F 1A 9F BE 77 00 64 74 65 73 74 02 01 */ uint8_t const payload[] = {0x81, 0xA3, 0x06, 0xFB, 0x40, 0x5E, 0xDD, 0x2F, 0x1A, 0x9F, 0xBE, 0x77, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x02, 0x01}; @@ -597,11 +622,12 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") WHEN("A payload containing a CBOR BaseVersion is parsed") { GIVEN("CloudProtocol::V2") { + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); CloudInt test = 0; - thing.addPropertyReal(test, "test", Permission::ReadWrite); + property_container.addPropertyReal(test, "test", Permission::ReadWrite); /* [{-1: 1, 0: "test", 2: 1}] = 81 A3 20 01 00 64 74 65 73 74 02 01 */ uint8_t const payload[] = {0x81, 0xA3, 0x20, 0x01, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x02, 0x01}; @@ -615,11 +641,12 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") WHEN("A payload containing a CBOR BaseName, BaseTime and Time is parsed") { GIVEN("CloudProtocol::V2") { + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); CloudInt test = 0; - thing.addPropertyReal(test, "test", Permission::ReadWrite); + property_container.addPropertyReal(test, "test", Permission::ReadWrite); /* [{-2: "base-name", -3: 654.321, 6: 123.456, 0: "test", 2: 1}] = 81 A5 21 69 62 61 73 65 2D 6E 61 6D 65 22 FB 40 84 72 91 68 72 B0 21 06 FB 40 5E DD 2F 1A 9F BE 77 00 64 74 65 73 74 02 01 @@ -635,11 +662,12 @@ SCENARIO("Arduino Cloud Properties are decoded", "[ArduinoCloudThing::decode]") WHEN("A payload containing a invalid CBOR key is parsed") { GIVEN("CloudProtocol::V2") { + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); CloudInt test = 0; - thing.addPropertyReal(test, "test", Permission::ReadWrite); + property_container.addPropertyReal(test, "test", Permission::ReadWrite); /* [{123: 123, 0: "test", 2: 1}] = 81 A3 18 7B 18 7B 00 64 74 65 73 74 02 01 */ uint8_t const payload[] = {0x81, 0xA3, 0x18, 0x7B, 0x18, 0x7B, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x02, 0x01}; diff --git a/extras/test/src/test_encode.cpp b/extras/test/src/test_encode.cpp index 6198b675b..b26def000 100644 --- a/extras/test/src/test_encode.cpp +++ b/extras/test/src/test_encode.cpp @@ -26,12 +26,13 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") WHEN("A 'bool' property is added") { GIVEN("CloudProtocol::V2") { + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); cbor::encode(thing); CloudBool test = true; - thing.addPropertyReal(test, "test", Permission::ReadWrite); + property_container.addPropertyReal(test, "test", Permission::ReadWrite); /* [{0: "test", 4: true}] = 9F A2 00 64 74 65 73 74 04 F5 FF*/ std::vector const expected = {0x9F, 0xA2, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x04, 0xF5, 0xFF}; @@ -45,13 +46,14 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") WHEN("A 'bool' property is added - light payload") { /*An integer identifier must be instead of the name of the property in order to have a shorter payload*/ GIVEN("CloudProtocol::V2") { + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); cbor::encode(thing); CloudBool test = true; /*The property is added with identifier 1 that will be used instead of the string "test" as property identifier*/ - thing.addPropertyReal(test, "test", Permission::ReadWrite, 1); + property_container.addPropertyReal(test, "test", Permission::ReadWrite, 1); /* [{0: 1, 4: true}] = 9F A2 00 01 04 F5 FF*/ std::vector const expected = {0x9F, 0xA2, 0x00, 0x01, 0x04, 0xF5, 0xFF}; @@ -64,12 +66,13 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") WHEN("A 'int' property is added") { GIVEN("CloudProtocol::V2") { + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); cbor::encode(thing); CloudInt int_test = 123; - thing.addPropertyReal(int_test, "test", Permission::ReadWrite); + property_container.addPropertyReal(int_test, "test", Permission::ReadWrite); /* [{0: "test", 3: 123}] = 9F A2 00 64 74 65 73 74 02 18 7B FF */ std::vector const expected = {0x9F, 0xA2, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x02, 0x18, 0x7B, 0xFF}; @@ -82,12 +85,13 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") WHEN("A 'float' property is added") { GIVEN("CloudProtocol::V2") { + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); cbor::encode(thing); CloudFloat float_test = 3.14159; - thing.addPropertyReal(float_test, "test", Permission::ReadWrite); + property_container.addPropertyReal(float_test, "test", Permission::ReadWrite); /* [{0: "test", 2: 3.141590118408203}] = 9F A2 00 64 74 65 73 74 02 FA 40 49 0F D0 FF */ std::vector const expected = {0x9F, 0xA2, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x02, 0xFA, 0x40, 0x49, 0x0F, 0xD0, 0xFF}; @@ -100,13 +104,14 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") WHEN("A 'String' property is added") { GIVEN("CloudProtocol::V2") { + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); cbor::encode(thing); CloudString string_test; string_test = "test"; - thing.addPropertyReal(string_test, "test", Permission::ReadWrite); + property_container.addPropertyReal(string_test, "test", Permission::ReadWrite); /* [{0: "test", 3: "test"}] = 9F A2 00 64 74 65 73 74 03 64 74 65 73 74 FF*/ std::vector const expected = {0x9F, 0xA2, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x03, 0x64, 0x74, 0x65, 0x73, 0x74, 0xFF}; @@ -119,12 +124,13 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") WHEN("A 'Location' property is added") { GIVEN("CloudProtocol::V2") { + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); cbor::encode(thing); CloudLocation location_test = CloudLocation(2.0f, 3.0f); - thing.addPropertyReal(location_test, "test", Permission::ReadWrite); + property_container.addPropertyReal(location_test, "test", Permission::ReadWrite); /* [{0: "test:lat", 3: 2},{0: "test:lon", 3: 3}] = 9F A2 00 68 74 65 73 74 3A 6C 61 74 02 FA 40 00 00 00 A2 00 68 74 65 73 74 3A 6C 6F 6E 02 FA 40 40 00 00 FF*/ std::vector const expected = { 0x9F, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x6C, 0x61, 0x74, 0x02, 0xFA, 0x40, 0x00, 0x00, 0x00, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x6C, 0x6F, 0x6E, 0x02, 0xFA, 0x40, 0x40, 0x00, 0x00, 0xFF }; @@ -137,12 +143,13 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") WHEN("A 'Color' property is added") { GIVEN("CloudProtocol::V2") { + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); cbor::encode(thing); CloudColor color_test = CloudColor(2.0, 2.0, 2.0); - thing.addPropertyReal(color_test, "test", Permission::ReadWrite); + property_container.addPropertyReal(color_test, "test", Permission::ReadWrite); /* [{0: "test:hue", 2: 2.0},{0: "test:sat", 2: 2.0},{0: "test:bri", 2: 2.0}] = 9F A2 00 68 74 65 73 74 3A 68 75 65 02 FA 40 00 00 00 A2 00 68 74 65 73 74 3A 73 61 74 02 FA 40 00 00 00 A2 00 68 74 65 73 74 3A 62 72 69 02 FA 40 00 00 00 FF*/ std::vector const expected = {0x9F, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x68, 0x75, 0x65, 0x02, 0xFA, 0x40, 0x00, 0x00, 0x00, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x73, 0x61, 0x74, 0x02, 0xFA, 0x40, 0x00, 0x00, 0x00, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x62, 0x72, 0x69, 0x02, 0xFA, 0x40, 0x00, 0x00, 0x00, 0xFF }; @@ -156,13 +163,14 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") WHEN("A 'Color' property is added - light payload") { /*An integer identifier must be encoded instead of the name of the property in order to have a shorter payload*/ GIVEN("CloudProtocol::V2") { + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); cbor::encode(thing); CloudColor color_test = CloudColor(2.0, 2.0, 2.0); /*The property is added with identifier 1 that will be used instead of the string "name" as property identifier */ - thing.addPropertyReal(color_test, "test", Permission::ReadWrite, 1); + property_container.addPropertyReal(color_test, "test", Permission::ReadWrite, 1); /* [{0: 257, 2: 2.0},{0: 513, 2: 2.0},{0: 769, 2: 2.0}] = 9F A2 00 19 01 01 02 FA 40 00 00 00 A2 00 19 02 01 02 FA 40 00 00 00 A2 00 19 03 01 02 FA 40 00 00 00 FF*/ std::vector const expected = {0x9F, 0xA2, 0x00, 0x19, 0x01, 0x01, 0x02, 0xFA, 0x40, 0x00, 0x00, 0x00, 0xA2, 0x00, 0x19, 0x02, 0x01, 0x02, 0xFA, 0x40, 0x00, 0x00, 0x00, 0xA2, 0x00, 0x19, 0x03, 0x01, 0x02, 0xFA, 0x40, 0x00, 0x00, 0x00, 0xFF }; @@ -175,12 +183,13 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") WHEN("A 'ColoredLight' property is added") { GIVEN("CloudProtocol::V2") { + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); cbor::encode(thing); CloudColoredLight color_test = CloudColoredLight(true, 2.0, 2.0, 2.0); - thing.addPropertyReal(color_test, "test", Permission::ReadWrite); + property_container.addPropertyReal(color_test, "test", Permission::ReadWrite); /* [{0: "test:swi", 4: true},{0: "test:hue", 2: 2.0},{0: "test:sat", 2: 2.0},{0: "test:bri", 2: 2.0}] = 83 A2 00 68 74 65 73 74 3A 73 77 69 04 F5 //A2 00 68 74 65 73 74 3A 68 75 65 02 FA 40 00 00 00 A2 00 68 74 65 73 74 3A 73 61 74 02 FA 40 00 00 00 A2 00 68 74 65 73 74 3A 62 72 69 02 FA 40 00 00 00 FF*/ std::vector const expected = {0x9F, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x73, 0x77, 0x69, 0x04, 0xF5, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x68, 0x75, 0x65, 0x02, 0xFA, 0x40, 0x00, 0x00, 0x00, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x73, 0x61, 0x74, 0x02, 0xFA, 0x40, 0x00, 0x00, 0x00, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x62, 0x72, 0x69, 0x02, 0xFA, 0x40, 0x00, 0x00, 0x00, 0xFF }; @@ -193,12 +202,13 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") WHEN("A 'Television' property is added") { GIVEN("CloudProtocol::V2") { + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); cbor::encode(thing); CloudTelevision tv_test = CloudTelevision(true, 50, false, PlaybackCommands::Play, InputValue::TV, 7); - thing.addPropertyReal(tv_test, "test", Permission::ReadWrite); + property_container.addPropertyReal(tv_test, "test", Permission::ReadWrite); /* [{0: "test:swi", 4: true},{0: "test:vol", 2: 50},{0: "test:mut", 2: false},{0: "test:pbc", 2: 3},{0: "test:inp", 2: 55},{0: "test:cha", 2: 7}] = 9F A2 00 68 74 65 73 74 3A 73 77 69 04 F5 A2 00 68 74 65 73 74 3A 76 6F 6C 02 18 32 A2 00 68 74 65 73 74 3A 6D 75 74 04 F4 A2 00 68 74 65 73 74 3A 70 62 63 02 03 A2 00 68 74 65 73 74 3A 69 6E 70 02 18 37 A2 00 68 74 65 73 74 3A 63 68 61 02 07 FF */ std::vector const expected = {0x9F, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x73, 0x77, 0x69, 0x04, 0xF5, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x76, 0x6F, 0x6C, 0x02, 0x18, 0x32, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x6D, 0x75, 0x74, 0x04, 0xF4, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x70, 0x62, 0x63, 0x02, 0x03, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x69, 0x6E, 0x70, 0x02, 0x18, 0x37, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x63, 0x68, 0x61, 0x02, 0x07, 0xFF}; @@ -211,12 +221,13 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") WHEN("A 'DimmedLight' property is added") { GIVEN("CloudProtocol::V2") { + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); cbor::encode(thing); CloudDimmedLight color_test = CloudDimmedLight(true, 2.0); - thing.addPropertyReal(color_test, "test", Permission::ReadWrite); + property_container.addPropertyReal(color_test, "test", Permission::ReadWrite); /* [{0: "test:swi", 4: true},{0: "test:hue", 2: 0.0},{0: "test:sat", 2: 0.0},{0: "test:bri", 2: 2.0}] = 83 A2 00 68 74 65 73 74 3A 73 77 69 04 F5 //A2 00 68 74 65 73 74 3A 68 75 65 02 FA 00 00 00 00 A2 00 68 74 65 73 74 3A 73 61 74 02 FA 00 00 00 00 A2 00 68 74 65 73 74 3A 62 72 69 02 FA 40 00 00 00 FF*/ std::vector const expected = {0x9F, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x73, 0x77, 0x69, 0x04, 0xF5, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x68, 0x75, 0x65, 0x02, 0xFA, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x73, 0x61, 0x74, 0x02, 0xFA, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x00, 0x68, 0x74, 0x65, 0x73, 0x74, 0x3A, 0x62, 0x72, 0x69, 0x02, 0xFA, 0x40, 0x00, 0x00, 0x00, 0xFF }; @@ -229,13 +240,14 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") WHEN("A light property is added") { GIVEN("CloudProtocol::V2") { + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); cbor::encode(thing); CloudLight test; test = true; - thing.addPropertyReal(test, "test", Permission::ReadWrite); + property_container.addPropertyReal(test, "test", Permission::ReadWrite); /* [{0: "test", 4: true}] = 9F A2 00 64 74 65 73 74 04 F5 FF*/ std::vector const expected = {0x9F, 0xA2, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x04, 0xF5, 0xFF}; @@ -248,13 +260,14 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") WHEN("A contact sensor property is added") { GIVEN("CloudProtocol::V2") { + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); cbor::encode(thing); CloudContactSensor test; test = true; - thing.addPropertyReal(test, "test", Permission::ReadWrite); + property_container.addPropertyReal(test, "test", Permission::ReadWrite); /* [{0: "test", 4: true}] = 9F A2 00 64 74 65 73 74 04 F5 FF*/ std::vector const expected = {0x9F, 0xA2, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x04, 0xF5, 0xFF}; @@ -267,13 +280,14 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") WHEN("A motion sensor property is added") { GIVEN("CloudProtocol::V2") { + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); cbor::encode(thing); CloudMotionSensor test; test = true; - thing.addPropertyReal(test, "test", Permission::ReadWrite); + property_container.addPropertyReal(test, "test", Permission::ReadWrite); /* [{0: "test", 4: true}] = 9F A2 00 64 74 65 73 74 04 F5 FF*/ std::vector const expected = {0x9F, 0xA2, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x04, 0xF5, 0xFF}; @@ -286,13 +300,14 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") WHEN("A smart plug property is added") { GIVEN("CloudProtocol::V2") { + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); cbor::encode(thing); CloudSmartPlug test; test = true; - thing.addPropertyReal(test, "test", Permission::ReadWrite); + property_container.addPropertyReal(test, "test", Permission::ReadWrite); /* [{0: "test", 4: true}] = 9F A2 00 64 74 65 73 74 04 F5 FF*/ std::vector const expected = {0x9F, 0xA2, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x04, 0xF5, 0xFF}; @@ -305,13 +320,14 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") WHEN("A Temperature property is added") { GIVEN("CloudProtocol::V2") { + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); cbor::encode(thing); CloudTemperature float_test; float_test = 3.14159; - thing.addPropertyReal(float_test, "test", Permission::ReadWrite); + property_container.addPropertyReal(float_test, "test", Permission::ReadWrite); /* [{0: "test", 2: 3.141590118408203}] = 9F A2 00 64 74 65 73 74 02 FA 40 49 0F D0 FF */ std::vector const expected = {0x9F, 0xA2, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x02, 0xFA, 0x40, 0x49, 0x0F, 0xD0, 0xFF}; @@ -324,13 +340,14 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") WHEN("A switch property is added") { GIVEN("CloudProtocol::V2") { + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); cbor::encode(thing); CloudSwitch test; test = true; - thing.addPropertyReal(test, "test", Permission::ReadWrite); + property_container.addPropertyReal(test, "test", Permission::ReadWrite); /* [{0: "test", 4: true}] = 9F A2 00 64 74 65 73 74 04 F5 FF*/ std::vector const expected = {0x9F, 0xA2, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x04, 0xF5, 0xFF}; @@ -343,8 +360,9 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") WHEN("Multiple properties are added") { GIVEN("CloudProtocol::V2") { + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); CloudInt int_test = 1; CloudBool bool_test = false; @@ -352,10 +370,10 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") CloudString str_test; str_test = "str_test"; - thing.addPropertyReal(int_test, "int_test", Permission::ReadWrite); - thing.addPropertyReal(bool_test, "bool_test", Permission::ReadWrite); - thing.addPropertyReal(float_test, "float_test", Permission::ReadWrite); - thing.addPropertyReal(str_test, "str_test", Permission::ReadWrite); + property_container.addPropertyReal(int_test, "int_test", Permission::ReadWrite); + property_container.addPropertyReal(bool_test, "bool_test", Permission::ReadWrite); + property_container.addPropertyReal(float_test, "float_test", Permission::ReadWrite); + property_container.addPropertyReal(str_test, "str_test", Permission::ReadWrite); /* [{0: "int_test", 2: 1}, {0: "bool_test", 4: false}, {0: "float_test", 2: 2.0}, {0: "str_test", 3: "str_test"}] = 9F A2 00 68 69 6E 74 5F 74 65 73 74 02 01 A2 00 6A 66 6C 6F 61 74 5F 74 65 73 74 02 FA A2 00 6A 66 6C 6F 61 74 5F 74 65 73 74 02 FA 40 00 00 00 A2 00 68 73 74 72 5F 74 65 73 74 03 68 73 74 72 5F 74 65 73 74 FF @@ -370,8 +388,9 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") WHEN("Multiple primitive properties are added") { GIVEN("CloudProtocol::V2") { + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); int int_test = 1; bool bool_test = false; @@ -379,17 +398,17 @@ SCENARIO("Arduino Cloud Properties are encoded", "[ArduinoCloudThing::encode]") String str_test; str_test = "str_test"; - std::unique_ptr i(new CloudWrapperInt(int_test)); - std::unique_ptr b(new CloudWrapperBool(bool_test)); - std::unique_ptr f(new CloudWrapperFloat(float_test)); - std::unique_ptr s(new CloudWrapperString(str_test)); + std::unique_ptr i(new CloudWrapperInt(int_test)); + std::unique_ptr b(new CloudWrapperBool(bool_test)); + std::unique_ptr f(new CloudWrapperFloat(float_test)); + std::unique_ptr s(new CloudWrapperString(str_test)); - thing.addPropertyReal(*i, "int_test", Permission::ReadWrite); - thing.addPropertyReal(*b, "bool_test", Permission::ReadWrite); - thing.addPropertyReal(*f, "float_test", Permission::ReadWrite); - thing.addPropertyReal(*s, "str_test", Permission::ReadWrite); + property_container.addPropertyReal(*i, "int_test", Permission::ReadWrite); + property_container.addPropertyReal(*b, "bool_test", Permission::ReadWrite); + property_container.addPropertyReal(*f, "float_test", Permission::ReadWrite); + property_container.addPropertyReal(*s, "str_test", Permission::ReadWrite); - thing.updateTimestampOnLocallyChangedProperties(); + property_container.updateTimestampOnLocallyChangedProperties(); /* [{0: "int_test", 2: 1}, {0: "bool_test", 4: false}, {0: "float_test", 2: 2.0}, {0: "str_test", 3: "str_test"}] = 9F A2 00 68 69 6E 74 5F 74 65 73 74 02 01 A2 00 6A 66 6C 6F 61 74 5F 74 65 73 74 02 FA A2 00 6A 66 6C 6F 61 74 5F 74 65 73 74 02 FA 40 00 00 00 A2 00 68 73 74 72 5F 74 65 73 74 03 68 73 74 72 5F 74 65 73 74 FF diff --git a/extras/test/src/test_publishEvery.cpp b/extras/test/src/test_publishEvery.cpp index 0de63ad41..5bea3eb08 100644 --- a/extras/test/src/test_publishEvery.cpp +++ b/extras/test/src/test_publishEvery.cpp @@ -19,13 +19,14 @@ SCENARIO("A Arduino cloud property is published periodically", "[ArduinoCloudThi /************************************************************************************/ GIVEN("CloudProtocol::V2") { + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); CloudBool test = true; unsigned long const PUBLISH_INTERVAL_SEC = 1 * SECONDS; - thing.addPropertyReal(test, "test", Permission::ReadWrite).publishEvery(PUBLISH_INTERVAL_SEC); + property_container.addPropertyReal(test, "test", Permission::ReadWrite).publishEvery(PUBLISH_INTERVAL_SEC); WHEN("t = 0 ms, publish interval = 1000 ms, 1st call to 'encode'") { set_millis(0); diff --git a/extras/test/src/test_publishOnChange.cpp b/extras/test/src/test_publishOnChange.cpp index a96f508c1..b549d5dd0 100644 --- a/extras/test/src/test_publishOnChange.cpp +++ b/extras/test/src/test_publishOnChange.cpp @@ -19,13 +19,14 @@ SCENARIO("A Arduino cloud property is published on value change", "[ArduinoCloud /************************************************************************************/ GIVEN("CloudProtocol::V2") { + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); CloudInt test = 10; int const DELTA = 6; - thing.addPropertyReal(test, "test", Permission::ReadWrite).publishOnChange(DELTA); + property_container.addPropertyReal(test, "test", Permission::ReadWrite).publishOnChange(DELTA); WHEN("test = 10, delta = 6, the property is encoded for the 1st time") { THEN("The property should be encoded") { diff --git a/extras/test/src/test_publishOnChangeRateLimit.cpp b/extras/test/src/test_publishOnChangeRateLimit.cpp index ab52afa3c..cf22ac2bf 100644 --- a/extras/test/src/test_publishOnChangeRateLimit.cpp +++ b/extras/test/src/test_publishOnChangeRateLimit.cpp @@ -19,14 +19,15 @@ SCENARIO("A Arduino cloud property is published on value change but the update r /************************************************************************************/ GIVEN("CloudProtocol::V2") { + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); CloudInt test = 0; int const MIN_DELTA = 0; unsigned long const MIN_TIME_BETWEEN_UPDATES_ms = 500; /* No updates faster than 500 ms */ - thing.addPropertyReal(test, "test", Permission::ReadWrite).publishOnChange(MIN_DELTA, MIN_TIME_BETWEEN_UPDATES_ms); + property_container.addPropertyReal(test, "test", Permission::ReadWrite).publishOnChange(MIN_DELTA, MIN_TIME_BETWEEN_UPDATES_ms); WHEN("t = 0 ms, min time between updates = 500 ms, property not modified, 1st call to 'encode'") { set_millis(0); diff --git a/extras/test/src/test_readOnly.cpp b/extras/test/src/test_readOnly.cpp index a090d512e..e06969168 100644 --- a/extras/test/src/test_readOnly.cpp +++ b/extras/test/src/test_readOnly.cpp @@ -19,11 +19,12 @@ SCENARIO("A Arduino cloud property is marked 'read only'", "[ArduinoCloudThing:: /************************************************************************************/ GIVEN("CloudProtocol::V2") { + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); CloudInt test = 0; - thing.addPropertyReal(test, "test", Permission::Read); + property_container.addPropertyReal(test, "test", Permission::Read); /* [{0: "test", 2: 7}] = 81 A2 00 64 74 65 73 74 02 07 */ uint8_t const payload[] = {0x81, 0xA2, 0x00, 0x64, 0x74, 0x65, 0x73, 0x74, 0x02, 0x07}; diff --git a/extras/test/src/test_writeOnly.cpp b/extras/test/src/test_writeOnly.cpp index 187cab4bb..fcef2458c 100644 --- a/extras/test/src/test_writeOnly.cpp +++ b/extras/test/src/test_writeOnly.cpp @@ -18,11 +18,12 @@ SCENARIO("A Arduino cloud property is marked 'write only'", "[ArduinoCloudThing::encode]") { /************************************************************************************/ + PropertyContainer property_container; ArduinoCloudThing thing; - thing.begin(); + thing.begin(&property_container); CloudInt test = 0; - thing.addPropertyReal(test, "test", Permission::Write); + property_container.addPropertyReal(test, "test", Permission::Write); REQUIRE(cbor::encode(thing).size() == 0); /* Since 'test' is 'write only' it should not be encoded */ diff --git a/src/ArduinoIoTCloud.cpp b/src/ArduinoIoTCloud.cpp index 4f4fdea0e..f1aaf91e9 100644 --- a/src/ArduinoIoTCloud.cpp +++ b/src/ArduinoIoTCloud.cpp @@ -30,12 +30,12 @@ void ArduinoIoTCloudClass::addCallback(ArduinoIoTCloudEvent const event, OnCloud _cloud_event_callback[static_cast(event)] = callback; } -void ArduinoIoTCloudClass::addPropertyReal(ArduinoCloudProperty& property, String name, permissionType permission_type, long seconds, void(*fn)(void), float minDelta, void(*synFn)(ArduinoCloudProperty & property)) +void ArduinoIoTCloudClass::addPropertyReal(Property& property, String name, permissionType permission_type, long seconds, void(*fn)(void), float minDelta, void(*synFn)(Property & property)) { addPropertyReal(property, name, -1, permission_type, seconds, fn, minDelta, synFn); } -void ArduinoIoTCloudClass::addPropertyReal(ArduinoCloudProperty& property, String name, int tag, permissionType permission_type, long seconds, void(*fn)(void), float minDelta, void(*synFn)(ArduinoCloudProperty & property)) +void ArduinoIoTCloudClass::addPropertyReal(Property& property, String name, int tag, permissionType permission_type, long seconds, void(*fn)(void), float minDelta, void(*synFn)(Property & property)) { Permission permission = Permission::ReadWrite; if (permission_type == READ) { @@ -47,98 +47,98 @@ void ArduinoIoTCloudClass::addPropertyReal(ArduinoCloudProperty& property, Strin } if (seconds == ON_CHANGE) { - _thing.addPropertyReal(property, name, permission, tag).publishOnChange(minDelta, DEFAULT_MIN_TIME_BETWEEN_UPDATES_MILLIS).onUpdate(fn).onSync(synFn); + _property_container.addPropertyReal(property, name, permission, tag).publishOnChange(minDelta, DEFAULT_MIN_TIME_BETWEEN_UPDATES_MILLIS).onUpdate(fn).onSync(synFn); } else { - _thing.addPropertyReal(property, name, permission, tag).publishEvery(seconds).onUpdate(fn).onSync(synFn); + _property_container.addPropertyReal(property, name, permission, tag).publishEvery(seconds).onUpdate(fn).onSync(synFn); } } -void ArduinoIoTCloudClass::addPropertyReal(bool& property, String name, permissionType permission_type, long seconds, void(*fn)(void), float minDelta, void(*synFn)(ArduinoCloudProperty & property)) +void ArduinoIoTCloudClass::addPropertyReal(bool& property, String name, permissionType permission_type, long seconds, void(*fn)(void), float minDelta, void(*synFn)(Property & property)) { addPropertyReal(property, name, -1, permission_type, seconds, fn, minDelta, synFn); } -void ArduinoIoTCloudClass::addPropertyReal(bool& property, String name, int tag, permissionType permission_type, long seconds, void(*fn)(void), float minDelta, void(*synFn)(ArduinoCloudProperty & property)) +void ArduinoIoTCloudClass::addPropertyReal(bool& property, String name, int tag, permissionType permission_type, long seconds, void(*fn)(void), float minDelta, void(*synFn)(Property & property)) { - ArduinoCloudProperty* p = new CloudWrapperBool(property); + Property* p = new CloudWrapperBool(property); addPropertyReal(*p, name, tag, permission_type, seconds, fn, minDelta, synFn); } -ArduinoCloudProperty& ArduinoIoTCloudClass::addPropertyReal(bool& property, String name, Permission const permission) +Property& ArduinoIoTCloudClass::addPropertyReal(bool& property, String name, Permission const permission) { return addPropertyReal(property, name, -1, permission); } -ArduinoCloudProperty& ArduinoIoTCloudClass::addPropertyReal(bool& property, String name, int tag, Permission const permission) +Property& ArduinoIoTCloudClass::addPropertyReal(bool& property, String name, int tag, Permission const permission) { - ArduinoCloudProperty* p = new CloudWrapperBool(property); - return _thing.addPropertyReal(*p, name, permission, tag); + Property* p = new CloudWrapperBool(property); + return _property_container.addPropertyReal(*p, name, permission, tag); } -void ArduinoIoTCloudClass::addPropertyReal(float& property, String name, permissionType permission_type, long seconds, void(*fn)(void), float minDelta, void(*synFn)(ArduinoCloudProperty & property)) +void ArduinoIoTCloudClass::addPropertyReal(float& property, String name, permissionType permission_type, long seconds, void(*fn)(void), float minDelta, void(*synFn)(Property & property)) { addPropertyReal(property, name, -1, permission_type, seconds, fn, minDelta, synFn); } -void ArduinoIoTCloudClass::addPropertyReal(float& property, String name, int tag, permissionType permission_type, long seconds, void(*fn)(void), float minDelta, void(*synFn)(ArduinoCloudProperty & property)) +void ArduinoIoTCloudClass::addPropertyReal(float& property, String name, int tag, permissionType permission_type, long seconds, void(*fn)(void), float minDelta, void(*synFn)(Property & property)) { - ArduinoCloudProperty* p = new CloudWrapperFloat(property); + Property* p = new CloudWrapperFloat(property); addPropertyReal(*p, name, tag, permission_type, seconds, fn, minDelta, synFn); } -ArduinoCloudProperty& ArduinoIoTCloudClass::addPropertyReal(float& property, String name, Permission const permission) +Property& ArduinoIoTCloudClass::addPropertyReal(float& property, String name, Permission const permission) { return addPropertyReal(property, name, -1, permission); } -ArduinoCloudProperty& ArduinoIoTCloudClass::addPropertyReal(float& property, String name, int tag, Permission const permission) +Property& ArduinoIoTCloudClass::addPropertyReal(float& property, String name, int tag, Permission const permission) { - ArduinoCloudProperty* p = new CloudWrapperFloat(property); - return _thing.addPropertyReal(*p, name, permission, tag); + Property* p = new CloudWrapperFloat(property); + return _property_container.addPropertyReal(*p, name, permission, tag); } -void ArduinoIoTCloudClass::addPropertyReal(int& property, String name, permissionType permission_type, long seconds, void(*fn)(void), float minDelta, void(*synFn)(ArduinoCloudProperty & property)) +void ArduinoIoTCloudClass::addPropertyReal(int& property, String name, permissionType permission_type, long seconds, void(*fn)(void), float minDelta, void(*synFn)(Property & property)) { addPropertyReal(property, name, -1, permission_type, seconds, fn, minDelta, synFn); } -void ArduinoIoTCloudClass::addPropertyReal(int& property, String name, int tag, permissionType permission_type, long seconds, void(*fn)(void), float minDelta, void(*synFn)(ArduinoCloudProperty & property)) +void ArduinoIoTCloudClass::addPropertyReal(int& property, String name, int tag, permissionType permission_type, long seconds, void(*fn)(void), float minDelta, void(*synFn)(Property & property)) { - ArduinoCloudProperty* p = new CloudWrapperInt(property); + Property* p = new CloudWrapperInt(property); addPropertyReal(*p, name, tag, permission_type, seconds, fn, minDelta, synFn); } -ArduinoCloudProperty& ArduinoIoTCloudClass::addPropertyReal(int& property, String name, Permission const permission) +Property& ArduinoIoTCloudClass::addPropertyReal(int& property, String name, Permission const permission) { return addPropertyReal(property, name, -1, permission); } -ArduinoCloudProperty& ArduinoIoTCloudClass::addPropertyReal(int& property, String name, int tag, Permission const permission) +Property& ArduinoIoTCloudClass::addPropertyReal(int& property, String name, int tag, Permission const permission) { - ArduinoCloudProperty* p = new CloudWrapperInt(property); - return _thing.addPropertyReal(*p, name, permission, tag); + Property* p = new CloudWrapperInt(property); + return _property_container.addPropertyReal(*p, name, permission, tag); } -void ArduinoIoTCloudClass::addPropertyReal(String& property, String name, permissionType permission_type, long seconds, void(*fn)(void), float minDelta, void(*synFn)(ArduinoCloudProperty & property)) +void ArduinoIoTCloudClass::addPropertyReal(String& property, String name, permissionType permission_type, long seconds, void(*fn)(void), float minDelta, void(*synFn)(Property & property)) { addPropertyReal(property, name, -1, permission_type, seconds, fn, minDelta, synFn); } -void ArduinoIoTCloudClass::addPropertyReal(String& property, String name, int tag, permissionType permission_type, long seconds, void(*fn)(void), float minDelta, void(*synFn)(ArduinoCloudProperty & property)) +void ArduinoIoTCloudClass::addPropertyReal(String& property, String name, int tag, permissionType permission_type, long seconds, void(*fn)(void), float minDelta, void(*synFn)(Property & property)) { - ArduinoCloudProperty* p = new CloudWrapperString(property); + Property* p = new CloudWrapperString(property); addPropertyReal(*p, name, tag, permission_type, seconds, fn, minDelta, synFn); } -ArduinoCloudProperty& ArduinoIoTCloudClass::addPropertyReal(String& property, String name, Permission const permission) +Property& ArduinoIoTCloudClass::addPropertyReal(String& property, String name, Permission const permission) { return addPropertyReal(property, name, -1, permission); } -ArduinoCloudProperty& ArduinoIoTCloudClass::addPropertyReal(String& property, String name, int tag, Permission const permission) +Property& ArduinoIoTCloudClass::addPropertyReal(String& property, String name, int tag, Permission const permission) { - ArduinoCloudProperty* p = new CloudWrapperString(property); - return _thing.addPropertyReal(*p, name, permission, tag); + Property* p = new CloudWrapperString(property); + return _property_container.addPropertyReal(*p, name, permission, tag); } /****************************************************************************** diff --git a/src/ArduinoIoTCloud.h b/src/ArduinoIoTCloud.h index 7933b167c..2f480d5df 100644 --- a/src/ArduinoIoTCloud.h +++ b/src/ArduinoIoTCloud.h @@ -29,10 +29,11 @@ #include "cbor/ArduinoCloudThing.h" -#include "cbor/types/CloudWrapperBool.h" -#include "cbor/types/CloudWrapperFloat.h" -#include "cbor/types/CloudWrapperInt.h" -#include "cbor/types/CloudWrapperString.h" +#include "property/PropertyContainer.h" +#include "property/types/CloudWrapperBool.h" +#include "property/types/CloudWrapperFloat.h" +#include "property/types/CloudWrapperInt.h" +#include "property/types/CloudWrapperString.h" #include "CloudSerial.h" @@ -103,16 +104,16 @@ class ArduinoIoTCloudClass * name of the property to identify a given property within a CBOR message. */ - void addPropertyReal(ArduinoCloudProperty& property, String name, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS); - void addPropertyReal(bool& property, String name, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS); - void addPropertyReal(float& property, String name, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS); - void addPropertyReal(int& property, String name, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS); - void addPropertyReal(String& property, String name, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS); + void addPropertyReal(Property& property, String name, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(Property & property) = CLOUD_WINS); + void addPropertyReal(bool& property, String name, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(Property & property) = CLOUD_WINS); + void addPropertyReal(float& property, String name, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(Property & property) = CLOUD_WINS); + void addPropertyReal(int& property, String name, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0, void(*synFn)(Property & property) = CLOUD_WINS); + void addPropertyReal(String& property, String name, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(Property & property) = CLOUD_WINS); - ArduinoCloudProperty& addPropertyReal(bool& property, String name, Permission const permission); - ArduinoCloudProperty& addPropertyReal(float& property, String name, Permission const permission); - ArduinoCloudProperty& addPropertyReal(int& property, String name, Permission const permission); - ArduinoCloudProperty& addPropertyReal(String& property, String name, int tag, Permission const permission); + Property& addPropertyReal(bool& property, String name, Permission const permission); + Property& addPropertyReal(float& property, String name, Permission const permission); + Property& addPropertyReal(int& property, String name, Permission const permission); + Property& addPropertyReal(String& property, String name, int tag, Permission const permission); /* The following methods are for MKR WAN 1300/1310 LoRa boards since * they use a number to identify a given property within a CBOR message. @@ -120,16 +121,16 @@ class ArduinoIoTCloudClass * important when using LoRa. */ - void addPropertyReal(ArduinoCloudProperty& property, String name, int tag, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS); - void addPropertyReal(bool& property, String name, int tag, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS); - void addPropertyReal(float& property, String name, int tag, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS); - void addPropertyReal(int& property, String name, int tag, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS); - void addPropertyReal(String& property, String name, int tag, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(ArduinoCloudProperty & property) = CLOUD_WINS); + void addPropertyReal(Property& property, String name, int tag, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(Property & property) = CLOUD_WINS); + void addPropertyReal(bool& property, String name, int tag, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(Property & property) = CLOUD_WINS); + void addPropertyReal(float& property, String name, int tag, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(Property & property) = CLOUD_WINS); + void addPropertyReal(int& property, String name, int tag, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0, void(*synFn)(Property & property) = CLOUD_WINS); + void addPropertyReal(String& property, String name, int tag, permissionType permission_type = READWRITE, long seconds = ON_CHANGE, void(*fn)(void) = NULL, float minDelta = 0.0f, void(*synFn)(Property & property) = CLOUD_WINS); - ArduinoCloudProperty& addPropertyReal(bool& property, String name, int tag, Permission const permission); - ArduinoCloudProperty& addPropertyReal(float& property, String name, int tag, Permission const permission); - ArduinoCloudProperty& addPropertyReal(int& property, String name, int tag, Permission const permission); - ArduinoCloudProperty& addPropertyReal(String& property, String name, Permission const permission); + Property& addPropertyReal(bool& property, String name, int tag, Permission const permission); + Property& addPropertyReal(float& property, String name, int tag, Permission const permission); + Property& addPropertyReal(int& property, String name, int tag, Permission const permission); + Property& addPropertyReal(String& property, String name, Permission const permission); protected: @@ -140,6 +141,7 @@ class ArduinoIoTCloudClass ConnectionHandler * _connection = nullptr; ArduinoCloudThing _thing; + PropertyContainer _property_container; ArduinoIoTConnectionStatus _iot_status = ArduinoIoTConnectionStatus::IDLE; NetworkConnectionState checkPhyConnection(); diff --git a/src/ArduinoIoTCloudLPWAN.cpp b/src/ArduinoIoTCloudLPWAN.cpp index 98f00d512..dd15ef826 100644 --- a/src/ArduinoIoTCloudLPWAN.cpp +++ b/src/ArduinoIoTCloudLPWAN.cpp @@ -56,14 +56,14 @@ int ArduinoIoTCloudLPWAN::begin(ConnectionHandler& connection, bool retry) { _connection = &connection; _retryEnable = retry; - _thing.begin(); + _thing.begin(&_property_container); return 1; } void ArduinoIoTCloudLPWAN::update() { // Check if a primitive property wrapper is locally changed - _thing.updateTimestampOnLocallyChangedProperties(); + _property_container.updateTimestampOnLocallyChangedProperties(); ArduinoIoTConnectionStatus next_iot_status = _iot_status; diff --git a/src/ArduinoIoTCloudTCP.cpp b/src/ArduinoIoTCloudTCP.cpp index cd529d40c..80688305f 100644 --- a/src/ArduinoIoTCloudTCP.cpp +++ b/src/ArduinoIoTCloudTCP.cpp @@ -134,8 +134,8 @@ int ArduinoIoTCloudTCP::begin(String brokerAddress, uint16_t brokerPort) _dataTopicIn = getTopic_datain(); _ota_topic_in = getTopic_ota_in(); - _thing.begin(); - _thing.registerGetTimeCallbackFunc(getTime); + _thing.begin(&_property_container); + _property_container.begin(getTime); printConnectionStatus(_iot_status); @@ -154,7 +154,7 @@ void ArduinoIoTCloudTCP::update() #endif /* OTA_ENABLED */ // Check if a primitive property wrapper is locally changed - _thing.updateTimestampOnLocallyChangedProperties(); + _property_container.updateTimestampOnLocallyChangedProperties(); if(checkPhyConnection() != NetworkConnectionState::CONNECTED) return; if(checkCloudConnection() != ArduinoIoTConnectionStatus::CONNECTED) return; diff --git a/src/cbor/ArduinoCloudThing.cpp b/src/cbor/ArduinoCloudThing.cpp index d7e2ff4cd..ad85cb552 100644 --- a/src/cbor/ArduinoCloudThing.cpp +++ b/src/cbor/ArduinoCloudThing.cpp @@ -27,30 +27,12 @@ #include "ArduinoCloudThing.h" -/****************************************************************************** - DEBUG FUNCTIONS - ******************************************************************************/ - -#if defined(DEBUG_MEMORY) && defined(ARDUINO_ARCH_SAMD) -extern "C" char *sbrk(int i); -void PrintFreeRam(void) { - char stack_dummy = 0; - //Serial.print("Free RAM: "); //Serial.println(&stack_dummy - sbrk(0)); -} -#endif - -#ifdef ARDUINO_ARCH_MRAA - #define Serial DebugSerial -#endif - /****************************************************************************** CTOR/DTOR ******************************************************************************/ ArduinoCloudThing::ArduinoCloudThing() : - _get_time_func{nullptr}, - _numPrimitivesProperties(0), - _numProperties(0), + _property_container{nullptr}, _isSyncMessage(false), _currentPropertyName(""), _currentPropertyBaseTime(0), @@ -61,11 +43,9 @@ ArduinoCloudThing::ArduinoCloudThing() : PUBLIC MEMBER FUNCTIONS ******************************************************************************/ -void ArduinoCloudThing::begin() { -} - -void ArduinoCloudThing::registerGetTimeCallbackFunc(GetTimeCallbackFunc func) { - _get_time_func = func; +void ArduinoCloudThing::begin(PropertyContainer * property_container) +{ + _property_container = property_container; } int ArduinoCloudThing::encode(uint8_t * data, size_t const size, bool lightPayload) { @@ -80,7 +60,7 @@ int ArduinoCloudThing::encode(uint8_t * data, size_t const size, bool lightPaylo return -1; } - if (appendChangedProperties(&arrayEncoder, lightPayload) < 1) { + if (_property_container->appendChangedProperties(&arrayEncoder, lightPayload) < 1) { return -1; } @@ -88,28 +68,10 @@ int ArduinoCloudThing::encode(uint8_t * data, size_t const size, bool lightPaylo return -1; } - #if defined(DEBUG_MEMORY) && defined(ARDUINO_ARCH_SAMD) - PrintFreeRam(); - #endif int const bytes_encoded = cbor_encoder_get_buffer_size(&encoder, data); return bytes_encoded; } -ArduinoCloudProperty& ArduinoCloudThing::addPropertyReal(ArduinoCloudProperty & property, String const & name, Permission const permission, int propertyIdentifier) { - property.init(name, permission, _get_time_func); - if (isPropertyInContainer(name)) { - return (*getProperty(name)); - } else { - if (property.isPrimitive()) { - _numPrimitivesProperties++; - } - _numProperties++; - addProperty(&property, propertyIdentifier); - return (property); - } - -} - void ArduinoCloudThing::decode(uint8_t const * const payload, size_t const length, bool isSyncMessage) { _isSyncMessage = isSyncMessage; @@ -161,81 +123,6 @@ void ArduinoCloudThing::decode(uint8_t const * const payload, size_t const lengt } } -bool ArduinoCloudThing::isPropertyInContainer(String const & name) -{ - return (getProperty(name) != nullptr); -} - -int ArduinoCloudThing::appendChangedProperties(CborEncoder * arrayEncoder, bool lightPayload) -{ - int appendedProperties = 0; - std::for_each(_property_list.begin(), - _property_list.end(), - [arrayEncoder, lightPayload, &appendedProperties](ArduinoCloudProperty * p) - { - if (p->shouldBeUpdated() && p->isReadableByCloud()) - { - p->append(arrayEncoder, lightPayload); - appendedProperties++; - } - }); - return appendedProperties; -} - -//retrieve property by name -ArduinoCloudProperty * ArduinoCloudThing::getProperty(String const & name) -{ - std::list::iterator iter; - - iter = std::find_if(_property_list.begin(), - _property_list.end(), - [name](ArduinoCloudProperty * p) -> bool - { - return (p->name() == name); - }); - - if (iter == _property_list.end()) - return nullptr; - else - return (*iter); -} - -//retrieve property by identifier -ArduinoCloudProperty * ArduinoCloudThing::getProperty(int const & pos) -{ - std::list::iterator iter; - - iter = std::find_if(_property_list.begin(), - _property_list.end(), - [pos](ArduinoCloudProperty * p) -> bool - { - return (p->identifier() == pos); - }); - - if (iter == _property_list.end()) - return nullptr; - else - return (*iter); -} - -// this function updates the timestamps on the primitive properties that have been modified locally since last cloud synchronization -void ArduinoCloudThing::updateTimestampOnLocallyChangedProperties() -{ - if (_numPrimitivesProperties > 0) - { - std::for_each(_property_list.begin(), - _property_list.end(), - [](ArduinoCloudProperty * p) - { - CloudWrapperBase * pbase = reinterpret_cast(p); - if (pbase->isPrimitive() && pbase->isChangedLocally() && pbase->isReadableByCloud()) - { - p->updateLocalTimestamp(); - } - }); - } -} - /****************************************************************************** PRIVATE MEMBER FUNCTIONS ******************************************************************************/ @@ -511,7 +398,7 @@ void ArduinoCloudThing::freeMapDataList(std::list * map_data_list } void ArduinoCloudThing::updateProperty(String propertyName, unsigned long cloudChangeEventTime) { - ArduinoCloudProperty* property = getProperty(propertyName); + Property* property = _property_container->getProperty(propertyName); if (property && property->isWriteableByCloud()) { property->setLastCloudChangeTimestamp(cloudChangeEventTime); property->setAttributesFromCloud(&_map_data_list); @@ -526,11 +413,11 @@ void ArduinoCloudThing::updateProperty(String propertyName, unsigned long cloudC // retrieve the property name by the identifier String ArduinoCloudThing::getPropertyNameByIdentifier(int propertyIdentifier) { - ArduinoCloudProperty* property; + Property* property; if (propertyIdentifier > 255) { - property = getProperty(propertyIdentifier & 255); + property = _property_container->getProperty(propertyIdentifier & 255); } else { - property = getProperty(propertyIdentifier); + property = _property_container->getProperty(propertyIdentifier); } return property->name(); } @@ -581,17 +468,17 @@ double ArduinoCloudThing::convertCborHalfFloatToDouble(uint16_t const half_val) return half_val & 0x8000 ? -val : val; } -void onAutoSync(ArduinoCloudProperty & property) { +void onAutoSync(Property & property) { if (property.getLastCloudChangeTimestamp() > property.getLastLocalChangeTimestamp()) { property.fromCloudToLocal(); property.execCallbackOnChange(); } } -void onForceCloudSync(ArduinoCloudProperty & property) { +void onForceCloudSync(Property & property) { property.fromCloudToLocal(); property.execCallbackOnChange(); } -void onForceDeviceSync(ArduinoCloudProperty & /* property */) { +void onForceDeviceSync(Property & /* property */) { } diff --git a/src/cbor/ArduinoCloudThing.h b/src/cbor/ArduinoCloudThing.h index 37f08b960..40cfdb58d 100644 --- a/src/cbor/ArduinoCloudThing.h +++ b/src/cbor/ArduinoCloudThing.h @@ -26,26 +26,25 @@ #undef min #include -#include "ArduinoCloudProperty.h" - -#include "types/CloudBool.h" -#include "types/CloudFloat.h" -#include "types/CloudInt.h" -#include "types/CloudString.h" -#include "types/CloudLocation.h" -#include "types/CloudColor.h" -#include "types/CloudWrapperBase.h" - -#include "types/automation/CloudColoredLight.h" -#include "types/automation/CloudContactSensor.h" -#include "types/automation/CloudDimmedLight.h" -#include "types/automation/CloudLight.h" -#include "types/automation/CloudMotionSensor.h" -#include "types/automation/CloudSmartPlug.h" -#include "types/automation/CloudSwitch.h" -#include "types/automation/CloudTemperature.h" -#include "types/automation/CloudTelevision.h" - +#include "../property/PropertyContainer.h" + +#include "../property/types/CloudBool.h" +#include "../property/types/CloudFloat.h" +#include "../property/types/CloudInt.h" +#include "../property/types/CloudString.h" +#include "../property/types/CloudLocation.h" +#include "../property/types/CloudColor.h" +#include "../property/types/CloudWrapperBase.h" + +#include "../property/types/automation/CloudColoredLight.h" +#include "../property/types/automation/CloudContactSensor.h" +#include "../property/types/automation/CloudDimmedLight.h" +#include "../property/types/automation/CloudLight.h" +#include "../property/types/automation/CloudMotionSensor.h" +#include "../property/types/automation/CloudSmartPlug.h" +#include "../property/types/automation/CloudSwitch.h" +#include "../property/types/automation/CloudTemperature.h" +#include "../property/types/automation/CloudTelevision.h" /****************************************************************************** CONSTANTS @@ -64,11 +63,11 @@ static long const DAYS = 86400; SYNCHRONIZATION CALLBACKS ******************************************************************************/ -void onAutoSync(ArduinoCloudProperty & property); +void onAutoSync(Property & property); #define MOST_RECENT_WINS onAutoSync -void onForceCloudSync(ArduinoCloudProperty & property); +void onForceCloudSync(Property & property); #define CLOUD_WINS onForceCloudSync -void onForceDeviceSync(ArduinoCloudProperty & property); +void onForceDeviceSync(Property & property); #define DEVICE_WINS onForceDeviceSync // The device property value is already the correct one. The cloud property value will be synchronized at the next update cycle. /****************************************************************************** @@ -80,10 +79,7 @@ class ArduinoCloudThing { public: ArduinoCloudThing(); - void begin(); - void registerGetTimeCallbackFunc(GetTimeCallbackFunc func); - //if propertyIdentifier is different from -1, an integer identifier is associated to the added property to be use instead of the property name when the parameter lightPayload is true in the encode method - ArduinoCloudProperty & addPropertyReal(ArduinoCloudProperty & property, String const & name, Permission const permission, int propertyIdentifier = -1); + void begin(PropertyContainer * property_container); /* encode return > 0 if a property has changed and encodes the changed properties in CBOR format into the provided buffer */ /* if lightPayload is true the integer identifier of the property will be encoded in the message instead of the property name in order to reduce the size of the message payload*/ @@ -91,18 +87,11 @@ class ArduinoCloudThing { /* decode a CBOR payload received from the cloud */ void decode(uint8_t const * const payload, size_t const length, bool isSyncMessage = false); - bool isPropertyInContainer(String const & name); - int appendChangedProperties(CborEncoder * arrayEncoder, bool lightPayload); - void updateTimestampOnLocallyChangedProperties(); void updateProperty(String propertyName, unsigned long cloudChangeEventTime); String getPropertyNameByIdentifier(int propertyIdentifier); private: - GetTimeCallbackFunc _get_time_func; - std::list _property_list; - /* Keep track of the number of primitive properties in the Thing. If 0 it allows the early exit in updateTimestampOnLocallyChangedProperties() */ - int _numPrimitivesProperties; - int _numProperties; + PropertyContainer * _property_container; /* Indicates the if the message received to be decoded is a response to the getLastValues inquiry */ bool _isSyncMessage; /* List of map data that will hold all the attributes of a property */ @@ -145,17 +134,6 @@ class ArduinoCloudThing { static bool ifNumericConvertToDouble(CborValue * value_iter, double * numeric_val); static double convertCborHalfFloatToDouble(uint16_t const half_val); void freeMapDataList(std::list * map_data_list); - inline void addProperty(ArduinoCloudProperty * property_obj, int propertyIdentifier) { - if (propertyIdentifier != -1) { - property_obj->setIdentifier(propertyIdentifier); - } else { - // if property identifier is -1, an incremental value will be assigned as identifier. - property_obj->setIdentifier(_numProperties); - } - _property_list.push_back(property_obj); - } - ArduinoCloudProperty * getProperty(String const & name); - ArduinoCloudProperty * getProperty(int const & identifier); }; diff --git a/src/cbor/ArduinoCloudProperty.cpp b/src/property/Property.cpp similarity index 76% rename from src/cbor/ArduinoCloudProperty.cpp rename to src/property/Property.cpp index b7abb50ea..52a1d2a58 100644 --- a/src/cbor/ArduinoCloudProperty.cpp +++ b/src/property/Property.cpp @@ -15,7 +15,7 @@ // a commercial license, send an email to license@arduino.cc. // -#include "ArduinoCloudProperty.h" +#include "Property.h" #undef max #undef min @@ -28,7 +28,7 @@ /****************************************************************************** CTOR/DTOR ******************************************************************************/ -ArduinoCloudProperty::ArduinoCloudProperty() +Property::Property() : _name(""), _min_delta_property(0.0f), _min_time_between_updates_millis(0), @@ -50,36 +50,36 @@ ArduinoCloudProperty::ArduinoCloudProperty() /****************************************************************************** PUBLIC MEMBER FUNCTIONS ******************************************************************************/ -void ArduinoCloudProperty::init(String const name, Permission const permission, GetTimeCallbackFunc func) { +void Property::init(String const name, Permission const permission, GetTimeCallbackFunc func) { _name = name; _permission = permission; _get_time_func = func; } -ArduinoCloudProperty & ArduinoCloudProperty::onUpdate(UpdateCallbackFunc func) { +Property & Property::onUpdate(UpdateCallbackFunc func) { _update_callback_func = func; return (*this); } -ArduinoCloudProperty & ArduinoCloudProperty::onSync(SyncCallbackFunc func) { +Property & Property::onSync(SyncCallbackFunc func) { _sync_callback_func = func; return (*this); } -ArduinoCloudProperty & ArduinoCloudProperty::publishOnChange(float const min_delta_property, unsigned long const min_time_between_updates_millis) { +Property & Property::publishOnChange(float const min_delta_property, unsigned long const min_time_between_updates_millis) { _update_policy = UpdatePolicy::OnChange; _min_delta_property = min_delta_property; _min_time_between_updates_millis = min_time_between_updates_millis; return (*this); } -ArduinoCloudProperty & ArduinoCloudProperty::publishEvery(unsigned long const seconds) { +Property & Property::publishEvery(unsigned long const seconds) { _update_policy = UpdatePolicy::TimeInterval; _update_interval_millis = (seconds * 1000); return (*this); } -bool ArduinoCloudProperty::shouldBeUpdated() { +bool Property::shouldBeUpdated() { if (!_has_been_updated_once) { return true; } @@ -98,7 +98,7 @@ bool ArduinoCloudProperty::shouldBeUpdated() { } } -void ArduinoCloudProperty::execCallbackOnChange() { +void Property::execCallbackOnChange() { if (_update_callback_func != NULL) { _update_callback_func(); } @@ -107,13 +107,13 @@ void ArduinoCloudProperty::execCallbackOnChange() { } } -void ArduinoCloudProperty::execCallbackOnSync() { +void Property::execCallbackOnSync() { if (_sync_callback_func != NULL) { _sync_callback_func(*this); } } -void ArduinoCloudProperty::append(CborEncoder *encoder, bool lightPayload) { +void Property::append(CborEncoder *encoder, bool lightPayload) { _lightPayload = lightPayload; _attributeIdentifier = 0; appendAttributesToCloudReal(encoder); @@ -122,35 +122,35 @@ void ArduinoCloudProperty::append(CborEncoder *encoder, bool lightPayload) { _last_updated_millis = millis(); } -void ArduinoCloudProperty::appendAttributeReal(bool value, String attributeName, CborEncoder *encoder) { +void Property::appendAttributeReal(bool value, String attributeName, CborEncoder *encoder) { appendAttributeName(attributeName, [value](CborEncoder & mapEncoder) { cbor_encode_int(&mapEncoder, static_cast(CborIntegerMapKey::BooleanValue)); cbor_encode_boolean(&mapEncoder, value); }, encoder); } -void ArduinoCloudProperty::appendAttributeReal(int value, String attributeName, CborEncoder *encoder) { +void Property::appendAttributeReal(int value, String attributeName, CborEncoder *encoder) { appendAttributeName(attributeName, [value](CborEncoder & mapEncoder) { cbor_encode_int(&mapEncoder, static_cast(CborIntegerMapKey::Value)); cbor_encode_int(&mapEncoder, value); }, encoder); } -void ArduinoCloudProperty::appendAttributeReal(float value, String attributeName, CborEncoder *encoder) { +void Property::appendAttributeReal(float value, String attributeName, CborEncoder *encoder) { appendAttributeName(attributeName, [value](CborEncoder & mapEncoder) { cbor_encode_int(&mapEncoder, static_cast(CborIntegerMapKey::Value)); cbor_encode_float(&mapEncoder, value); }, encoder); } -void ArduinoCloudProperty::appendAttributeReal(String value, String attributeName, CborEncoder *encoder) { +void Property::appendAttributeReal(String value, String attributeName, CborEncoder *encoder) { appendAttributeName(attributeName, [value](CborEncoder & mapEncoder) { cbor_encode_int(&mapEncoder, static_cast(CborIntegerMapKey::StringValue)); cbor_encode_text_stringz(&mapEncoder, value.c_str()); }, encoder); } -void ArduinoCloudProperty::appendAttributeName(String attributeName, std::functionappendValue, CborEncoder *encoder) { +void Property::appendAttributeName(String attributeName, std::functionappendValue, CborEncoder *encoder) { if (attributeName != "") { // when the attribute name string is not empty, the attribute identifier is incremented in order to be encoded in the message if the _lightPayload flag is set _attributeIdentifier++; @@ -177,13 +177,13 @@ void ArduinoCloudProperty::appendAttributeName(String attributeName, std::functi cbor_encoder_close_container(encoder, &mapEncoder); } -void ArduinoCloudProperty::setAttributesFromCloud(std::list * map_data_list) { +void Property::setAttributesFromCloud(std::list * map_data_list) { _map_data_list = map_data_list; _attributeIdentifier = 0; setAttributesFromCloud(); } -void ArduinoCloudProperty::setAttributeReal(bool& value, String attributeName) { +void Property::setAttributeReal(bool& value, String attributeName) { setAttributeReal(attributeName, [&value](CborMapData * md) { // Manage the case to have boolean values received as integers 0/1 if (md->bool_val.isSet()) { @@ -200,25 +200,25 @@ void ArduinoCloudProperty::setAttributeReal(bool& value, String attributeName) { }); } -void ArduinoCloudProperty::setAttributeReal(int& value, String attributeName) { +void Property::setAttributeReal(int& value, String attributeName) { setAttributeReal(attributeName, [&value](CborMapData * md) { value = md->val.get(); }); } -void ArduinoCloudProperty::setAttributeReal(float& value, String attributeName) { +void Property::setAttributeReal(float& value, String attributeName) { setAttributeReal(attributeName, [&value](CborMapData * md) { value = md->val.get(); }); } -void ArduinoCloudProperty::setAttributeReal(String& value, String attributeName) { +void Property::setAttributeReal(String& value, String attributeName) { setAttributeReal(attributeName, [&value](CborMapData * md) { value = md->str_val.get(); }); } -void ArduinoCloudProperty::setAttributeReal(String attributeName, std::functionsetValue) +void Property::setAttributeReal(String attributeName, std::functionsetValue) { if (attributeName != "") { _attributeIdentifier++; @@ -252,14 +252,14 @@ void ArduinoCloudProperty::setAttributeReal(String attributeName, std::function< }); } -String ArduinoCloudProperty::getAttributeName(String propertyName, char separator) { +String Property::getAttributeName(String propertyName, char separator) { int colonPos; String attributeName = ""; (colonPos = propertyName.indexOf(separator)) != -1 ? attributeName = propertyName.substring(colonPos + 1) : ""; return attributeName; } -void ArduinoCloudProperty::updateLocalTimestamp() { +void Property::updateLocalTimestamp() { if (isReadableByCloud()) { if (_get_time_func) { _last_local_change_timestamp = _get_time_func(); @@ -267,22 +267,22 @@ void ArduinoCloudProperty::updateLocalTimestamp() { } } -void ArduinoCloudProperty::setLastCloudChangeTimestamp(unsigned long cloudChangeEventTime) { +void Property::setLastCloudChangeTimestamp(unsigned long cloudChangeEventTime) { _last_cloud_change_timestamp = cloudChangeEventTime; } -void ArduinoCloudProperty::setLastLocalChangeTimestamp(unsigned long localChangeTime) { +void Property::setLastLocalChangeTimestamp(unsigned long localChangeTime) { _last_local_change_timestamp = localChangeTime; } -unsigned long ArduinoCloudProperty::getLastCloudChangeTimestamp() { +unsigned long Property::getLastCloudChangeTimestamp() { return _last_cloud_change_timestamp; } -unsigned long ArduinoCloudProperty::getLastLocalChangeTimestamp() { +unsigned long Property::getLastLocalChangeTimestamp() { return _last_local_change_timestamp; } -void ArduinoCloudProperty::setIdentifier(int identifier) { +void Property::setIdentifier(int identifier) { _identifier = identifier; } diff --git a/src/cbor/ArduinoCloudProperty.h b/src/property/Property.h similarity index 91% rename from src/cbor/ArduinoCloudProperty.h rename to src/property/Property.h index 1e7011f45..c9a936b99 100644 --- a/src/cbor/ArduinoCloudProperty.h +++ b/src/property/Property.h @@ -34,7 +34,7 @@ #include #include -#include "lib/tinycbor/cbor-lib.h" +#include "../cbor/lib/tinycbor/cbor-lib.h" #define appendAttributesToCloud() appendAttributesToCloudReal(CborEncoder *encoder) #define appendAttribute(x) appendAttributeReal(x, getAttributeName(#x, '.'), encoder) @@ -127,17 +127,17 @@ typedef unsigned long(*GetTimeCallbackFunc)(); CLASS DECLARATION ******************************************************************************/ -class ArduinoCloudProperty { - typedef void(*SyncCallbackFunc)(ArduinoCloudProperty &property); +class Property { + typedef void(*SyncCallbackFunc)(Property &property); public: - ArduinoCloudProperty(); + Property(); void init(String const name, Permission const permission, GetTimeCallbackFunc func); - /* Composable configuration of the ArduinoCloudProperty class */ - ArduinoCloudProperty & onUpdate(UpdateCallbackFunc func); - ArduinoCloudProperty & onSync(SyncCallbackFunc func); - ArduinoCloudProperty & publishOnChange(float const min_delta_property, unsigned long const min_time_between_updates_millis = 0); - ArduinoCloudProperty & publishEvery(unsigned long const seconds); + /* Composable configuration of the Property class */ + Property & onUpdate(UpdateCallbackFunc func); + Property & onSync(SyncCallbackFunc func); + Property & publishOnChange(float const min_delta_property, unsigned long const min_time_between_updates_millis = 0); + Property & publishEvery(unsigned long const seconds); inline String name() const { return _name; @@ -194,7 +194,7 @@ class ArduinoCloudProperty { Permission _permission; GetTimeCallbackFunc _get_time_func; UpdateCallbackFunc _update_callback_func; - void (*_sync_callback_func)(ArduinoCloudProperty &property); + void (*_sync_callback_func)(Property &property); UpdatePolicy _update_policy; bool _has_been_updated_once, @@ -217,7 +217,7 @@ class ArduinoCloudProperty { PROTOTYPE FREE FUNCTIONs ******************************************************************************/ -inline bool operator == (ArduinoCloudProperty const & lhs, ArduinoCloudProperty const & rhs) { +inline bool operator == (Property const & lhs, Property const & rhs) { return (lhs.name() == rhs.name()); } diff --git a/src/property/PropertyContainer.cpp b/src/property/PropertyContainer.cpp new file mode 100644 index 000000000..4067ee920 --- /dev/null +++ b/src/property/PropertyContainer.cpp @@ -0,0 +1,151 @@ +/* + This file is part of ArduinoIoTCloud. + + Copyright 2020 ARDUINO SA (http://www.arduino.cc/) + + This software is released under the GNU General Public License version 3, + which covers the main part of arduino-cli. + The terms of this license can be found at: + https://www.gnu.org/licenses/gpl-3.0.en.html + + You can be released from the requirements of the above licenses by purchasing + a commercial license. Buying such a license is mandatory if you want to modify or + otherwise use the software for commercial activities involving the Arduino + software without disclosing the source code of your own applications. To purchase + a commercial license, send an email to license@arduino.cc. +*/ + +/****************************************************************************** + INCLUDE + ******************************************************************************/ + +#include "PropertyContainer.h" + +#include + +#include "types/CloudWrapperBase.h" + +/****************************************************************************** + CTOR/DTOR + ******************************************************************************/ + +PropertyContainer::PropertyContainer() +: _numProperties{0} +, _numPrimitivesProperties{0} +, _get_time_func{nullptr} +{ + +} + +/****************************************************************************** + PUBLIC MEMBER FUNCTIONS + ******************************************************************************/ + +void PropertyContainer::begin(GetTimeCallbackFunc func) +{ + _get_time_func = func; +} + +Property & PropertyContainer::addPropertyReal(Property & property, String const & name, Permission const permission, int propertyIdentifier) +{ + /* Check wether or not the property already has been added to the container */ + Property * p = getProperty(name); + if(p != nullptr) return (*p); + + /* Initialize property and add it to the container */ + property.init(name, permission, _get_time_func); + + if (property.isPrimitive()) { _numPrimitivesProperties++; } + _numProperties++; + addProperty(&property, propertyIdentifier); + return property; +} + + +Property * PropertyContainer::getProperty(String const & name) +{ + std::list::iterator iter; + + iter = std::find_if(_property_list.begin(), + _property_list.end(), + [name](Property * p) -> bool + { + return (p->name() == name); + }); + + if (iter == _property_list.end()) + return nullptr; + else + return (*iter); +} + +Property * PropertyContainer::getProperty(int const identifier) +{ + std::list::iterator iter; + + iter = std::find_if(_property_list.begin(), + _property_list.end(), + [identifier](Property * p) -> bool + { + return (p->identifier() == identifier); + }); + + if (iter == _property_list.end()) + return nullptr; + else + return (*iter); +} + +int PropertyContainer::appendChangedProperties(CborEncoder * arrayEncoder, bool lightPayload) +{ + int appendedProperties = 0; + std::for_each(_property_list.begin(), + _property_list.end(), + [arrayEncoder, lightPayload, &appendedProperties](Property * p) + { + if (p->shouldBeUpdated() && p->isReadableByCloud()) + { + p->append(arrayEncoder, lightPayload); + appendedProperties++; + } + }); + return appendedProperties; +} + +void PropertyContainer::updateTimestampOnLocallyChangedProperties() +{ + /* This function updates the timestamps on the primitive properties + * that have been modified locally since last cloud synchronization + */ + if (_numPrimitivesProperties > 0) + { + std::for_each(_property_list.begin(), + _property_list.end(), + [](Property * p) + { + CloudWrapperBase * pbase = reinterpret_cast(p); + if (pbase->isPrimitive() && pbase->isChangedLocally() && pbase->isReadableByCloud()) + { + p->updateLocalTimestamp(); + } + }); + } +} + +/****************************************************************************** + PRIVATE MEMBER FUNCTIONS + ******************************************************************************/ + +void PropertyContainer::addProperty(Property * property_obj, int propertyIdentifier) +{ + if (propertyIdentifier != -1) + { + property_obj->setIdentifier(propertyIdentifier); + } + /* If property identifier is -1, an incremental value will be assigned as identifier. */ + else + { + property_obj->setIdentifier(_numProperties); + } + _property_list.push_back(property_obj); +} diff --git a/src/property/PropertyContainer.h b/src/property/PropertyContainer.h new file mode 100644 index 000000000..2e23f5ff6 --- /dev/null +++ b/src/property/PropertyContainer.h @@ -0,0 +1,69 @@ +/* + This file is part of ArduinoIoTCloud. + + Copyright 2020 ARDUINO SA (http://www.arduino.cc/) + + This software is released under the GNU General Public License version 3, + which covers the main part of arduino-cli. + The terms of this license can be found at: + https://www.gnu.org/licenses/gpl-3.0.en.html + + You can be released from the requirements of the above licenses by purchasing + a commercial license. Buying such a license is mandatory if you want to modify or + otherwise use the software for commercial activities involving the Arduino + software without disclosing the source code of your own applications. To purchase + a commercial license, send an email to license@arduino.cc. +*/ + +#ifndef ARDUINO_PROPERTY_CONTAINER_H_ +#define ARDUINO_PROPERTY_CONTAINER_H_ + +/****************************************************************************** + INCLUDE + ******************************************************************************/ + +#include "Property.h" + +#undef max +#undef min +#include + +/****************************************************************************** + CLASS DECLARATION + ******************************************************************************/ + +class PropertyContainer +{ + +public: + + PropertyContainer(); + + + void begin(GetTimeCallbackFunc func); + + + Property & addPropertyReal(Property & property, String const & name, Permission const permission, int propertyIdentifier = -1); + + + Property * getProperty (String const & name); + Property * getProperty (int const identifier); + + + int appendChangedProperties(CborEncoder * arrayEncoder, bool lightPayload); + void updateTimestampOnLocallyChangedProperties(); + + + +private: + + int _numProperties; + int _numPrimitivesProperties; + GetTimeCallbackFunc _get_time_func; + std::list _property_list; + + void addProperty(Property * property_obj, int propertyIdentifier); + +}; + +#endif /* ARDUINO_PROPERTY_CONTAINER_H_ */ \ No newline at end of file diff --git a/src/cbor/types/CloudBool.h b/src/property/types/CloudBool.h similarity index 96% rename from src/cbor/types/CloudBool.h rename to src/property/types/CloudBool.h index 9a0295f25..2ac989629 100644 --- a/src/cbor/types/CloudBool.h +++ b/src/property/types/CloudBool.h @@ -23,7 +23,7 @@ ******************************************************************************/ #include -#include "../ArduinoCloudProperty.h" +#include "../Property.h" /****************************************************************************** CLASS DECLARATION @@ -31,7 +31,7 @@ -class CloudBool : public ArduinoCloudProperty { +class CloudBool : public Property { protected: bool _value, _cloud_value; diff --git a/src/cbor/types/CloudColor.h b/src/property/types/CloudColor.h similarity index 98% rename from src/cbor/types/CloudColor.h rename to src/property/types/CloudColor.h index cddc69751..ea126122a 100644 --- a/src/cbor/types/CloudColor.h +++ b/src/property/types/CloudColor.h @@ -24,7 +24,7 @@ #include #include -#include "../ArduinoCloudProperty.h" +#include "../Property.h" /****************************************************************************** CLASS DECLARATION @@ -153,7 +153,7 @@ class Color { }; -class CloudColor : public ArduinoCloudProperty { +class CloudColor : public Property { private: Color _value, _cloud_value; diff --git a/src/cbor/types/CloudFloat.h b/src/property/types/CloudFloat.h similarity index 97% rename from src/cbor/types/CloudFloat.h rename to src/property/types/CloudFloat.h index 6c9a2014d..33860f9c3 100644 --- a/src/cbor/types/CloudFloat.h +++ b/src/property/types/CloudFloat.h @@ -25,7 +25,7 @@ ******************************************************************************/ #include -#include "../ArduinoCloudProperty.h" +#include "../Property.h" /****************************************************************************** CLASS DECLARATION @@ -33,7 +33,7 @@ -class CloudFloat : public ArduinoCloudProperty { +class CloudFloat : public Property { protected: float _value, _cloud_value; @@ -46,7 +46,7 @@ class CloudFloat : public ArduinoCloudProperty { return _value; } virtual bool isDifferentFromCloud() { - return _value != _cloud_value && (abs(_value - _cloud_value) >= ArduinoCloudProperty::_min_delta_property); + return _value != _cloud_value && (abs(_value - _cloud_value) >= Property::_min_delta_property); } virtual void fromCloudToLocal() { _value = _cloud_value; diff --git a/src/cbor/types/CloudInt.h b/src/property/types/CloudInt.h similarity index 97% rename from src/cbor/types/CloudInt.h rename to src/property/types/CloudInt.h index 7093fb05a..97a3c6a15 100644 --- a/src/cbor/types/CloudInt.h +++ b/src/property/types/CloudInt.h @@ -23,7 +23,7 @@ ******************************************************************************/ #include -#include "../ArduinoCloudProperty.h" +#include "../Property.h" /****************************************************************************** CLASS DECLARATION @@ -31,7 +31,7 @@ -class CloudInt : public ArduinoCloudProperty { +class CloudInt : public Property { private: int _value, _cloud_value; @@ -44,7 +44,7 @@ class CloudInt : public ArduinoCloudProperty { return _value; } virtual bool isDifferentFromCloud() { - return _value != _cloud_value && (abs(_value - _cloud_value) >= ArduinoCloudProperty::_min_delta_property); + return _value != _cloud_value && (abs(_value - _cloud_value) >= Property::_min_delta_property); } virtual void fromCloudToLocal() { _value = _cloud_value; diff --git a/src/cbor/types/CloudLocation.h b/src/property/types/CloudLocation.h similarity index 93% rename from src/cbor/types/CloudLocation.h rename to src/property/types/CloudLocation.h index 79d65543d..cbb74754a 100644 --- a/src/cbor/types/CloudLocation.h +++ b/src/property/types/CloudLocation.h @@ -24,7 +24,7 @@ #include #include -#include "../ArduinoCloudProperty.h" +#include "../Property.h" /****************************************************************************** CLASS DECLARATION @@ -56,7 +56,7 @@ class Location { } }; -class CloudLocation : public ArduinoCloudProperty { +class CloudLocation : public Property { private: Location _value, _cloud_value; @@ -65,7 +65,7 @@ class CloudLocation : public ArduinoCloudProperty { CloudLocation(float lat, float lon) : _value(lat, lon), _cloud_value(lat, lon) {} virtual bool isDifferentFromCloud() { float const distance = Location::distance(_value, _cloud_value); - return _value != _cloud_value && (abs(distance) >= ArduinoCloudProperty::_min_delta_property); + return _value != _cloud_value && (abs(distance) >= Property::_min_delta_property); } CloudLocation& operator=(Location aLocation) { diff --git a/src/cbor/types/CloudString.h b/src/property/types/CloudString.h similarity index 96% rename from src/cbor/types/CloudString.h rename to src/property/types/CloudString.h index 800a6ddab..b2fd447ef 100644 --- a/src/cbor/types/CloudString.h +++ b/src/property/types/CloudString.h @@ -23,7 +23,7 @@ ******************************************************************************/ #include -#include "../ArduinoCloudProperty.h" +#include "../Property.h" /****************************************************************************** CLASS DECLARATION @@ -31,7 +31,7 @@ -class CloudString : public ArduinoCloudProperty { +class CloudString : public Property { private: String _value, _cloud_value; diff --git a/src/cbor/types/CloudWrapperBase.h b/src/property/types/CloudWrapperBase.h similarity index 93% rename from src/cbor/types/CloudWrapperBase.h rename to src/property/types/CloudWrapperBase.h index 3d5910c55..9efd86100 100644 --- a/src/cbor/types/CloudWrapperBase.h +++ b/src/property/types/CloudWrapperBase.h @@ -23,13 +23,13 @@ ******************************************************************************/ #include -#include "../ArduinoCloudProperty.h" +#include "../Property.h" /****************************************************************************** CLASS DECLARATION ******************************************************************************/ -class CloudWrapperBase : public ArduinoCloudProperty { +class CloudWrapperBase : public Property { public: virtual bool isChangedLocally() = 0; }; diff --git a/src/cbor/types/CloudWrapperBool.h b/src/property/types/CloudWrapperBool.h similarity index 100% rename from src/cbor/types/CloudWrapperBool.h rename to src/property/types/CloudWrapperBool.h diff --git a/src/cbor/types/CloudWrapperFloat.h b/src/property/types/CloudWrapperFloat.h similarity index 96% rename from src/cbor/types/CloudWrapperFloat.h rename to src/property/types/CloudWrapperFloat.h index 0c69f6df6..d30b1d86c 100644 --- a/src/cbor/types/CloudWrapperFloat.h +++ b/src/property/types/CloudWrapperFloat.h @@ -39,7 +39,7 @@ class CloudWrapperFloat : public CloudWrapperBase { public: CloudWrapperFloat(float& v) : _primitive_value(v), _cloud_value(v), _local_value(v) {} virtual bool isDifferentFromCloud() { - return _primitive_value != _cloud_value && (abs(_primitive_value - _cloud_value) >= ArduinoCloudProperty::_min_delta_property); + return _primitive_value != _cloud_value && (abs(_primitive_value - _cloud_value) >= Property::_min_delta_property); } virtual void fromCloudToLocal() { _primitive_value = _cloud_value; diff --git a/src/cbor/types/CloudWrapperInt.h b/src/property/types/CloudWrapperInt.h similarity index 96% rename from src/cbor/types/CloudWrapperInt.h rename to src/property/types/CloudWrapperInt.h index 88c4a2f9a..db83ab1db 100644 --- a/src/cbor/types/CloudWrapperInt.h +++ b/src/property/types/CloudWrapperInt.h @@ -37,7 +37,7 @@ class CloudWrapperInt : public CloudWrapperBase { public: CloudWrapperInt(int& v) : _primitive_value(v), _cloud_value(v), _local_value(v) {} virtual bool isDifferentFromCloud() { - return _primitive_value != _cloud_value && (abs(_primitive_value - _cloud_value) >= ArduinoCloudProperty::_min_delta_property); + return _primitive_value != _cloud_value && (abs(_primitive_value - _cloud_value) >= Property::_min_delta_property); } virtual void fromCloudToLocal() { _primitive_value = _cloud_value; diff --git a/src/cbor/types/CloudWrapperString.h b/src/property/types/CloudWrapperString.h similarity index 100% rename from src/cbor/types/CloudWrapperString.h rename to src/property/types/CloudWrapperString.h diff --git a/src/cbor/types/automation/CloudColoredLight.h b/src/property/types/automation/CloudColoredLight.h similarity index 100% rename from src/cbor/types/automation/CloudColoredLight.h rename to src/property/types/automation/CloudColoredLight.h diff --git a/src/cbor/types/automation/CloudContactSensor.h b/src/property/types/automation/CloudContactSensor.h similarity index 100% rename from src/cbor/types/automation/CloudContactSensor.h rename to src/property/types/automation/CloudContactSensor.h diff --git a/src/cbor/types/automation/CloudDimmedLight.h b/src/property/types/automation/CloudDimmedLight.h similarity index 97% rename from src/cbor/types/automation/CloudDimmedLight.h rename to src/property/types/automation/CloudDimmedLight.h index 9dbfe1204..ecb9a6d92 100644 --- a/src/cbor/types/automation/CloudDimmedLight.h +++ b/src/property/types/automation/CloudDimmedLight.h @@ -24,7 +24,7 @@ #include #include -#include "../../ArduinoCloudProperty.h" +#include "../../Property.h" /****************************************************************************** CLASS DECLARATION @@ -46,7 +46,7 @@ class DimmedLight { }; -class CloudDimmedLight : public ArduinoCloudProperty { +class CloudDimmedLight : public Property { private: DimmedLight _value, _cloud_value; diff --git a/src/cbor/types/automation/CloudLight.h b/src/property/types/automation/CloudLight.h similarity index 100% rename from src/cbor/types/automation/CloudLight.h rename to src/property/types/automation/CloudLight.h diff --git a/src/cbor/types/automation/CloudMotionSensor.h b/src/property/types/automation/CloudMotionSensor.h similarity index 100% rename from src/cbor/types/automation/CloudMotionSensor.h rename to src/property/types/automation/CloudMotionSensor.h diff --git a/src/cbor/types/automation/CloudSmartPlug.h b/src/property/types/automation/CloudSmartPlug.h similarity index 100% rename from src/cbor/types/automation/CloudSmartPlug.h rename to src/property/types/automation/CloudSmartPlug.h diff --git a/src/cbor/types/automation/CloudSwitch.h b/src/property/types/automation/CloudSwitch.h similarity index 100% rename from src/cbor/types/automation/CloudSwitch.h rename to src/property/types/automation/CloudSwitch.h diff --git a/src/cbor/types/automation/CloudTelevision.h b/src/property/types/automation/CloudTelevision.h similarity index 98% rename from src/cbor/types/automation/CloudTelevision.h rename to src/property/types/automation/CloudTelevision.h index a2ee63b48..c96a49e45 100644 --- a/src/cbor/types/automation/CloudTelevision.h +++ b/src/property/types/automation/CloudTelevision.h @@ -23,7 +23,7 @@ ******************************************************************************/ #include -#include "../../ArduinoCloudProperty.h" +#include "../../Property.h" /****************************************************************************** ENUM @@ -136,7 +136,7 @@ class Television { }; -class CloudTelevision : public ArduinoCloudProperty { +class CloudTelevision : public Property { private: Television _value, _cloud_value; diff --git a/src/cbor/types/automation/CloudTemperature.h b/src/property/types/automation/CloudTemperature.h similarity index 100% rename from src/cbor/types/automation/CloudTemperature.h rename to src/property/types/automation/CloudTemperature.h