diff --git a/examples/ArduinoIoTCloud-Advanced/ArduinoIoTCloud-Advanced.ino b/examples/ArduinoIoTCloud-Advanced/ArduinoIoTCloud-Advanced.ino index 09585040..127c67fa 100644 --- a/examples/ArduinoIoTCloud-Advanced/ArduinoIoTCloud-Advanced.ino +++ b/examples/ArduinoIoTCloud-Advanced/ArduinoIoTCloud-Advanced.ino @@ -2,7 +2,7 @@ This sketch demonstrates how to use more complex cloud data types such as a colour or coordinates. IMPORTANT: - This sketch works with WiFi, GSM, NB, Ethernet and Lora enabled boards supported by Arduino IoT Cloud. + This sketch works with Notecard, WiFi, GSM, NB, Ethernet and Lora enabled boards supported by Arduino IoT Cloud. On a LoRa board, if it is configured as a class A device (default and preferred option), values from Cloud dashboard are received only after a value is sent to Cloud. diff --git a/examples/ArduinoIoTCloud-Advanced/arduino_secrets.h b/examples/ArduinoIoTCloud-Advanced/arduino_secrets.h index 44a9e21d..48f14eb5 100644 --- a/examples/ArduinoIoTCloud-Advanced/arduino_secrets.h +++ b/examples/ArduinoIoTCloud-Advanced/arduino_secrets.h @@ -3,7 +3,7 @@ /* A complete list of supported boards with WiFi is available here: * https://github.com/arduino-libraries/ArduinoIoTCloud/#what */ -#if defined(BOARD_HAS_WIFI) +#if defined(USE_NOTECARD) || defined(BOARD_HAS_WIFI) #define SECRET_WIFI_SSID "YOUR_WIFI_NETWORK_NAME" #define SECRET_WIFI_PASS "YOUR_WIFI_PASSWORD" #endif diff --git a/examples/ArduinoIoTCloud-Advanced/thingProperties.h b/examples/ArduinoIoTCloud-Advanced/thingProperties.h index 43187104..77c397e0 100644 --- a/examples/ArduinoIoTCloud-Advanced/thingProperties.h +++ b/examples/ArduinoIoTCloud-Advanced/thingProperties.h @@ -2,7 +2,7 @@ #include #include "arduino_secrets.h" -#if !(defined(BOARD_HAS_WIFI) || defined(BOARD_HAS_GSM) || defined(BOARD_HAS_LORA) || \ +#if !(defined(USE_NOTECARD) || defined(BOARD_HAS_WIFI) || defined(BOARD_HAS_GSM) || defined(BOARD_HAS_LORA) || \ defined(BOARD_HAS_NB) || defined(BOARD_HAS_ETHERNET) || defined(BOARD_HAS_CATM1_NBIOT)) #error "Please check Arduino IoT Cloud supported boards list: https://github.com/arduino-libraries/ArduinoIoTCloud/#what" #endif @@ -11,6 +11,14 @@ #define BOARD_ID "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" #endif +#if defined(USE_NOTECARD) + /* The Notecard can provide connectivity to almost any board via ESLOV (I2C) + * or UART. An empty string (or the default value provided below) will not + * override the Notecard's existing configuration. + * Learn more at: https://dev.blues.io */ + #define NOTECARD_PRODUCT_UID "com.domain.you:product" +#endif + void onSwitchButtonChange(); void onColorChange(); @@ -23,7 +31,7 @@ void initProperties() { ArduinoCloud.setBoardId(BOARD_ID); ArduinoCloud.setSecretDeviceKey(SECRET_DEVICE_KEY); #endif -#if defined(BOARD_HAS_WIFI) || defined(BOARD_HAS_GSM) || defined(BOARD_HAS_NB) || defined(BOARD_HAS_ETHERNET) || defined(BOARD_HAS_CATM1_NBIOT) +#if defined(USE_NOTECARD) || defined(BOARD_HAS_WIFI) || defined(BOARD_HAS_GSM) || defined(BOARD_HAS_NB) || defined(BOARD_HAS_ETHERNET) || defined(BOARD_HAS_CATM1_NBIOT) ArduinoCloud.addProperty(switchButton, Permission::Write).onUpdate(onSwitchButtonChange); ArduinoCloud.addProperty(location, Permission::Read).publishOnChange(0.0f); ArduinoCloud.addProperty(color, Permission::ReadWrite).onUpdate(onColorChange); @@ -34,7 +42,9 @@ void initProperties() { #endif } -#if defined(BOARD_HAS_WIFI) +#if defined(USE_NOTECARD) + NotecardConnectionHandler ArduinoIoTPreferredConnection(NOTECARD_PRODUCT_UID); +#elif defined(BOARD_HAS_WIFI) WiFiConnectionHandler ArduinoIoTPreferredConnection(SECRET_WIFI_SSID, SECRET_WIFI_PASS); #elif defined(BOARD_HAS_GSM) GSMConnectionHandler ArduinoIoTPreferredConnection(SECRET_PIN, SECRET_APN, SECRET_LOGIN, SECRET_PASS); diff --git a/examples/ArduinoIoTCloud-Basic/ArduinoIoTCloud-Basic.ino b/examples/ArduinoIoTCloud-Basic/ArduinoIoTCloud-Basic.ino index a37996b3..5dfbf02b 100644 --- a/examples/ArduinoIoTCloud-Basic/ArduinoIoTCloud-Basic.ino +++ b/examples/ArduinoIoTCloud-Basic/ArduinoIoTCloud-Basic.ino @@ -6,7 +6,7 @@ * When you flip the switch in the Cloud dashboard the onboard LED lights gets turned ON or OFF. IMPORTANT: - This sketch works with WiFi, GSM, NB, Ethernet and Lora enabled boards supported by Arduino IoT Cloud. + This sketch works with Notecard, WiFi, GSM, NB, Ethernet and Lora enabled boards supported by Arduino IoT Cloud. On a LoRa board, if it is configured as a class A device (default and preferred option), values from Cloud dashboard are received only after a value is sent to Cloud. diff --git a/examples/ArduinoIoTCloud-Basic/arduino_secrets.h b/examples/ArduinoIoTCloud-Basic/arduino_secrets.h index 44a9e21d..48f14eb5 100644 --- a/examples/ArduinoIoTCloud-Basic/arduino_secrets.h +++ b/examples/ArduinoIoTCloud-Basic/arduino_secrets.h @@ -3,7 +3,7 @@ /* A complete list of supported boards with WiFi is available here: * https://github.com/arduino-libraries/ArduinoIoTCloud/#what */ -#if defined(BOARD_HAS_WIFI) +#if defined(USE_NOTECARD) || defined(BOARD_HAS_WIFI) #define SECRET_WIFI_SSID "YOUR_WIFI_NETWORK_NAME" #define SECRET_WIFI_PASS "YOUR_WIFI_PASSWORD" #endif diff --git a/examples/ArduinoIoTCloud-Basic/thingProperties.h b/examples/ArduinoIoTCloud-Basic/thingProperties.h index 4193b440..a4718828 100644 --- a/examples/ArduinoIoTCloud-Basic/thingProperties.h +++ b/examples/ArduinoIoTCloud-Basic/thingProperties.h @@ -2,7 +2,7 @@ #include #include "arduino_secrets.h" -#if !(defined(BOARD_HAS_WIFI) || defined(BOARD_HAS_GSM) || defined(BOARD_HAS_LORA) || \ +#if !(defined(USE_NOTECARD) || defined(BOARD_HAS_WIFI) || defined(BOARD_HAS_GSM) || defined(BOARD_HAS_LORA) || \ defined(BOARD_HAS_NB) || defined(BOARD_HAS_ETHERNET) || defined(BOARD_HAS_CATM1_NBIOT)) #error "Please check Arduino IoT Cloud supported boards list: https://github.com/arduino-libraries/ArduinoIoTCloud/#what" #endif @@ -11,6 +11,14 @@ #define BOARD_ID "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" #endif +#if defined(USE_NOTECARD) + /* The Notecard can provide connectivity to almost any board via ESLOV (I2C) + * or UART. An empty string (or the default value provided below) will not + * override the Notecard's existing configuration. + * Learn more at: https://dev.blues.io */ + #define NOTECARD_PRODUCT_UID "com.domain.you:product" +#endif + void onLedChange(); bool led; @@ -26,14 +34,16 @@ void initProperties() { ArduinoCloud.addProperty(led, Permission::Write).onUpdate(onLedChange); ArduinoCloud.addProperty(potentiometer, Permission::Read).publishOnChange(10); ArduinoCloud.addProperty(seconds, Permission::Read).publishOnChange(1); -#elif defined(BOARD_HAS_LORA) +#elif defined(USE_NOTECARD) || defined(BOARD_HAS_LORA) ArduinoCloud.addProperty(led, 1, Permission::ReadWrite).onUpdate(onLedChange); ArduinoCloud.addProperty(potentiometer, 2, Permission::Read).publishOnChange(10); ArduinoCloud.addProperty(seconds, 3, Permission::Read).publishEvery(5 * MINUTES); #endif } -#if defined(BOARD_HAS_ETHERNET) +#if defined(USE_NOTECARD) + NotecardConnectionHandler ArduinoIoTPreferredConnection(NOTECARD_PRODUCT_UID); +#elif defined(BOARD_HAS_ETHERNET) /* DHCP mode */ //EthernetConnectionHandler ArduinoIoTPreferredConnection; /* Manual mode. It will fallback in DHCP mode if SECRET_OPTIONAL_IP is invalid or equal to "0.0.0.0" */ diff --git a/examples/ArduinoIoTCloud-Callbacks/ArduinoIoTCloud-Callbacks.ino b/examples/ArduinoIoTCloud-Callbacks/ArduinoIoTCloud-Callbacks.ino index 1d39a2f5..6ce12070 100644 --- a/examples/ArduinoIoTCloud-Callbacks/ArduinoIoTCloud-Callbacks.ino +++ b/examples/ArduinoIoTCloud-Callbacks/ArduinoIoTCloud-Callbacks.ino @@ -18,7 +18,7 @@ One function per event can be assigned. IMPORTANT: - This sketch works with WiFi, GSM, NB, Ethernet and Lora enabled boards supported by Arduino IoT Cloud. + This sketch works with Notecard, WiFi, GSM, NB, Ethernet and Lora enabled boards supported by Arduino IoT Cloud. On a LoRa board, if it is configured as a class A device (default and preferred option), values from Cloud dashboard are received only after a value is sent to Cloud. diff --git a/examples/ArduinoIoTCloud-Callbacks/arduino_secrets.h b/examples/ArduinoIoTCloud-Callbacks/arduino_secrets.h index 44a9e21d..48f14eb5 100644 --- a/examples/ArduinoIoTCloud-Callbacks/arduino_secrets.h +++ b/examples/ArduinoIoTCloud-Callbacks/arduino_secrets.h @@ -3,7 +3,7 @@ /* A complete list of supported boards with WiFi is available here: * https://github.com/arduino-libraries/ArduinoIoTCloud/#what */ -#if defined(BOARD_HAS_WIFI) +#if defined(USE_NOTECARD) || defined(BOARD_HAS_WIFI) #define SECRET_WIFI_SSID "YOUR_WIFI_NETWORK_NAME" #define SECRET_WIFI_PASS "YOUR_WIFI_PASSWORD" #endif diff --git a/examples/ArduinoIoTCloud-Callbacks/thingProperties.h b/examples/ArduinoIoTCloud-Callbacks/thingProperties.h index 8f2b5055..62b7dc77 100644 --- a/examples/ArduinoIoTCloud-Callbacks/thingProperties.h +++ b/examples/ArduinoIoTCloud-Callbacks/thingProperties.h @@ -2,7 +2,7 @@ #include #include "arduino_secrets.h" -#if !(defined(BOARD_HAS_WIFI) || defined(BOARD_HAS_GSM) || defined(BOARD_HAS_LORA) || \ +#if !(defined(USE_NOTECARD) || defined(BOARD_HAS_WIFI) || defined(BOARD_HAS_GSM) || defined(BOARD_HAS_LORA) || \ defined(BOARD_HAS_NB) || defined(BOARD_HAS_ETHERNET) || defined(BOARD_HAS_CATM1_NBIOT)) #error "Please check Arduino IoT Cloud supported boards list: https://github.com/arduino-libraries/ArduinoIoTCloud/#what" #endif @@ -11,6 +11,14 @@ #define BOARD_ID "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" #endif +#if defined(USE_NOTECARD) + /* The Notecard can provide connectivity to almost any board via ESLOV (I2C) + * or UART. An empty string (or the default value provided below) will not + * override the Notecard's existing configuration. + * Learn more at: https://dev.blues.io */ + #define NOTECARD_PRODUCT_UID "com.domain.you:product" +#endif + void initProperties() { #if defined(BOARD_HAS_SECRET_KEY) ArduinoCloud.setBoardId(BOARD_ID); @@ -18,7 +26,9 @@ void initProperties() { #endif } -#if defined(BOARD_HAS_WIFI) +#if defined(USE_NOTECARD) + NotecardConnectionHandler ArduinoIoTPreferredConnection(NOTECARD_PRODUCT_UID); +#elif defined(BOARD_HAS_WIFI) WiFiConnectionHandler ArduinoIoTPreferredConnection(SECRET_WIFI_SSID, SECRET_WIFI_PASS); #elif defined(BOARD_HAS_GSM) GSMConnectionHandler ArduinoIoTPreferredConnection(SECRET_PIN, SECRET_APN, SECRET_LOGIN, SECRET_PASS); diff --git a/examples/ArduinoIoTCloud-DeferredOTA/arduino_secrets.h b/examples/ArduinoIoTCloud-DeferredOTA/arduino_secrets.h index e784c441..ced6852a 100644 --- a/examples/ArduinoIoTCloud-DeferredOTA/arduino_secrets.h +++ b/examples/ArduinoIoTCloud-DeferredOTA/arduino_secrets.h @@ -3,7 +3,7 @@ /* A complete list of supported boards with WiFi is available here: * https://github.com/arduino-libraries/ArduinoIoTCloud/#what */ -#if defined(BOARD_HAS_WIFI) +#if defined(USE_NOTECARD) || defined(BOARD_HAS_WIFI) #define SECRET_WIFI_SSID "YOUR_WIFI_NETWORK_NAME" #define SECRET_WIFI_PASS "YOUR_WIFI_PASSWORD" #endif diff --git a/examples/ArduinoIoTCloud-Schedule/ArduinoIoTCloud-Schedule.ino b/examples/ArduinoIoTCloud-Schedule/ArduinoIoTCloud-Schedule.ino index 5b41d149..c1c1b38f 100644 --- a/examples/ArduinoIoTCloud-Schedule/ArduinoIoTCloud-Schedule.ino +++ b/examples/ArduinoIoTCloud-Schedule/ArduinoIoTCloud-Schedule.ino @@ -2,7 +2,7 @@ This sketch demonstrates how to use the cloud schedule variable type. IMPORTANT: - This sketch works with WiFi, GSM, NB and Ethernet enabled boards supported by Arduino IoT Cloud. + This sketch works with Notecard, WiFi, GSM, NB and Ethernet enabled boards supported by Arduino IoT Cloud. */ diff --git a/examples/ArduinoIoTCloud-Schedule/arduino_secrets.h b/examples/ArduinoIoTCloud-Schedule/arduino_secrets.h index 44a9e21d..48f14eb5 100644 --- a/examples/ArduinoIoTCloud-Schedule/arduino_secrets.h +++ b/examples/ArduinoIoTCloud-Schedule/arduino_secrets.h @@ -3,7 +3,7 @@ /* A complete list of supported boards with WiFi is available here: * https://github.com/arduino-libraries/ArduinoIoTCloud/#what */ -#if defined(BOARD_HAS_WIFI) +#if defined(USE_NOTECARD) || defined(BOARD_HAS_WIFI) #define SECRET_WIFI_SSID "YOUR_WIFI_NETWORK_NAME" #define SECRET_WIFI_PASS "YOUR_WIFI_PASSWORD" #endif diff --git a/examples/ArduinoIoTCloud-Schedule/thingProperties.h b/examples/ArduinoIoTCloud-Schedule/thingProperties.h index 8d2d7dfc..e9a1e65c 100644 --- a/examples/ArduinoIoTCloud-Schedule/thingProperties.h +++ b/examples/ArduinoIoTCloud-Schedule/thingProperties.h @@ -2,7 +2,7 @@ #include #include "arduino_secrets.h" -#if !(defined(BOARD_HAS_WIFI) || defined(BOARD_HAS_GSM) || defined(BOARD_HAS_LORA) || \ +#if !(defined(USE_NOTECARD) || defined(BOARD_HAS_WIFI) || defined(BOARD_HAS_GSM) || defined(BOARD_HAS_LORA) || \ defined(BOARD_HAS_NB) || defined(BOARD_HAS_ETHERNET) || defined(BOARD_HAS_CATM1_NBIOT)) #error "Please check Arduino IoT Cloud supported boards list: https://github.com/arduino-libraries/ArduinoIoTCloud/#what" #endif @@ -11,6 +11,14 @@ #define BOARD_ID "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" #endif +#if defined(USE_NOTECARD) + /* The Notecard can provide connectivity to almost any board via ESLOV (I2C) + * or UART. An empty string (or the default value provided below) will not + * override the Notecard's existing configuration. + * Learn more at: https://dev.blues.io */ + #define NOTECARD_PRODUCT_UID "com.domain.you:product" +#endif + void onSwitchButtonChange(); bool switchButton; @@ -27,7 +35,7 @@ void initProperties() { ArduinoCloud.setBoardId(BOARD_ID); ArduinoCloud.setSecretDeviceKey(SECRET_DEVICE_KEY); #endif -#if defined(BOARD_HAS_WIFI) || defined(BOARD_HAS_GSM) || defined(BOARD_HAS_NB) || defined(BOARD_HAS_ETHERNET) || defined(BOARD_HAS_CATM1_NBIOT) +#if defined(USE_NOTECARD) || defined(BOARD_HAS_WIFI) || defined(BOARD_HAS_GSM) || defined(BOARD_HAS_NB) || defined(BOARD_HAS_ETHERNET) || defined(BOARD_HAS_CATM1_NBIOT) ArduinoCloud.addProperty(switchButton, Permission::Write); ArduinoCloud.addProperty(oneShot, Permission::ReadWrite); ArduinoCloud.addProperty(minute, Permission::ReadWrite); @@ -41,7 +49,9 @@ void initProperties() { #endif } -#if defined(BOARD_HAS_WIFI) +#if defined(USE_NOTECARD) + NotecardConnectionHandler ArduinoIoTPreferredConnection(NOTECARD_PRODUCT_UID); +#elif defined(BOARD_HAS_WIFI) WiFiConnectionHandler ArduinoIoTPreferredConnection(SECRET_WIFI_SSID, SECRET_WIFI_PASS); #elif defined(BOARD_HAS_GSM) GSMConnectionHandler ArduinoIoTPreferredConnection(SECRET_PIN, SECRET_APN, SECRET_LOGIN, SECRET_PASS); diff --git a/examples/utility/ArduinoIoTCloud_Travis_CI/ArduinoIoTCloud_Travis_CI.ino b/examples/utility/ArduinoIoTCloud_Travis_CI/ArduinoIoTCloud_Travis_CI.ino index 4d478e06..48007697 100644 --- a/examples/utility/ArduinoIoTCloud_Travis_CI/ArduinoIoTCloud_Travis_CI.ino +++ b/examples/utility/ArduinoIoTCloud_Travis_CI/ArduinoIoTCloud_Travis_CI.ino @@ -4,7 +4,7 @@ Arduino IoT Cloud API. IMPORTANT: - This sketch works with WiFi, GSM, NB, Ethernet and Lora enabled boards supported by Arduino IoT Cloud. + This sketch works with Notecard, WiFi, GSM, NB, Ethernet and Lora enabled boards supported by Arduino IoT Cloud. On a LoRa board, if it is configured as a class A device (default and preferred option), values from Cloud dashboard are received only after a value is sent to Cloud. diff --git a/examples/utility/ArduinoIoTCloud_Travis_CI/arduino_secrets.h b/examples/utility/ArduinoIoTCloud_Travis_CI/arduino_secrets.h index 2ae0cefa..ed0ec7fe 100644 --- a/examples/utility/ArduinoIoTCloud_Travis_CI/arduino_secrets.h +++ b/examples/utility/ArduinoIoTCloud_Travis_CI/arduino_secrets.h @@ -3,7 +3,7 @@ /* A complete list of supported boards with WiFi is available here: * https://github.com/arduino-libraries/ArduinoIoTCloud/#what */ -#if defined(BOARD_HAS_WIFI) +#if defined(USE_NOTECARD) || defined(BOARD_HAS_WIFI) #define SECRET_WIFI_SSID "YOUR_WIFI_NETWORK_NAME" #define SECRET_WIFI_PASS "YOUR_WIFI_PASSWORD" #endif diff --git a/examples/utility/ArduinoIoTCloud_Travis_CI/thingProperties.h b/examples/utility/ArduinoIoTCloud_Travis_CI/thingProperties.h index 36604ebf..2882e671 100644 --- a/examples/utility/ArduinoIoTCloud_Travis_CI/thingProperties.h +++ b/examples/utility/ArduinoIoTCloud_Travis_CI/thingProperties.h @@ -2,7 +2,7 @@ #include #include "arduino_secrets.h" -#if !(defined(BOARD_HAS_WIFI) || defined(BOARD_HAS_GSM) || defined(BOARD_HAS_LORA) || \ +#if !(defined(USE_NOTECARD) || defined(BOARD_HAS_WIFI) || defined(BOARD_HAS_GSM) || defined(BOARD_HAS_LORA) || \ defined(BOARD_HAS_NB) || defined(BOARD_HAS_ETHERNET) || defined(BOARD_HAS_CATM1_NBIOT)) #error "Please check Arduino IoT Cloud supported boards list: https://github.com/arduino-libraries/ArduinoIoTCloud/#what" #endif @@ -19,6 +19,14 @@ #define THING_ID "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" #endif +#if defined(USE_NOTECARD) + /* The Notecard can provide connectivity to almost any board via ESLOV (I2C) + * or UART. An empty string (or the default value provided below) will not + * override the Notecard's existing configuration. + * Learn more at: https://dev.blues.io */ + #define NOTECARD_PRODUCT_UID "com.domain.you:product" +#endif + /****************************************************************************** GLOBAL CONSTANTS ******************************************************************************/ @@ -54,7 +62,9 @@ String str_property_6; String str_property_7; String str_property_8; -#if defined(BOARD_HAS_WIFI) +#if defined(USE_NOTECARD) + NotecardConnectionHandler ArduinoIoTPreferredConnection(NOTECARD_PRODUCT_UID); +#elif defined(BOARD_HAS_WIFI) WiFiConnectionHandler ArduinoIoTPreferredConnection(SECRET_WIFI_SSID, SECRET_WIFI_PASS); #elif defined(BOARD_HAS_GSM) GSMConnectionHandler ArduinoIoTPreferredConnection(SECRET_PIN, SECRET_APN, SECRET_LOGIN, SECRET_PASS); @@ -83,7 +93,7 @@ void onStringPropertyChange(); /****************************************************************************** FUNCTIONS ******************************************************************************/ -#if defined(BOARD_HAS_WIFI) || defined(BOARD_HAS_GSM) || defined (BOARD_HAS_NB) || defined (BOARD_HAS_CATM1_NBIOT) +#if defined(USE_NOTECARD) || defined(BOARD_HAS_WIFI) || defined(BOARD_HAS_GSM) || defined (BOARD_HAS_NB) || defined (BOARD_HAS_CATM1_NBIOT) void initProperties() { #if defined(BOARD_HAS_SECRET_KEY) ArduinoCloud.setBoardId(BOARD_ID); diff --git a/library.properties b/library.properties index c478c9ec..652d7f9c 100644 --- a/library.properties +++ b/library.properties @@ -6,6 +6,6 @@ sentence=This library allows connecting to the Arduino IoT Cloud service. paragraph=It provides a ConnectionManager to handle connection/disconnection, property-change updates and events callbacks. The supported boards are MKR GSM, MKR1000 and WiFi101. category=Communication url=https://github.com/arduino-libraries/ArduinoIoTCloud -architectures=mbed,samd,esp8266,mbed_nano,mbed_portenta,mbed_nicla,esp32,mbed_opta,mbed_giga,renesas_portenta,renesas_uno,mbed_edge +architectures=mbed,samd,esp8266,mbed_nano,mbed_portenta,mbed_nicla,esp32,mbed_opta,mbed_giga,renesas_portenta,renesas_uno,mbed_edge,stm32 includes=ArduinoIoTCloud.h depends=Arduino_ConnectionHandler,Arduino_DebugUtils,Arduino_SecureElement,ArduinoMqttClient,ArduinoECCX08,RTCZero,Adafruit SleepyDog Library,ArduinoHttpClient diff --git a/src/AIoTC_Config.h b/src/AIoTC_Config.h index d7a1bf8f..8e66a1c3 100644 --- a/src/AIoTC_Config.h +++ b/src/AIoTC_Config.h @@ -18,6 +18,12 @@ #ifndef ARDUINO_AIOTC_CONFIG_H_ #define ARDUINO_AIOTC_CONFIG_H_ +#if defined __has_include + #if __has_include () + #define USE_NOTECARD + #endif +#endif + #include /****************************************************************************** @@ -52,6 +58,8 @@ * AUTOMATICALLY CONFIGURED DEFINES ******************************************************************************/ +#if !defined(USE_NOTECARD) + #if defined(ARDUINO_SAMD_MKRWIFI1010) || defined(ARDUINO_SAMD_NANO_33_IOT) #define OTA_STORAGE_SNU (1) #else @@ -114,11 +122,6 @@ #define HAS_TCP #endif -#if defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_NICLA_VISION) || defined(ARDUINO_OPTA) || defined(ARDUINO_GIGA) - #define BEAR_SSL_CLIENT_IBUF_SIZE (16384 + 325) // Allows download from storage API - #define BOARD_STM32H7 -#endif - #if defined(ARDUINO_NANO_RP2040_CONNECT) #define BEAR_SSL_CLIENT_IBUF_SIZE (16384 + 325) // Allows download from storage API #endif @@ -138,6 +141,13 @@ #define BOARD_HAS_SECURE_ELEMENT #endif +#endif // USE_NOTECARD + +#if defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_NICLA_VISION) || defined(ARDUINO_OPTA) || defined(ARDUINO_GIGA) + #define BEAR_SSL_CLIENT_IBUF_SIZE (16384 + 325) // Allows download from storage API + #define BOARD_STM32H7 +#endif + /****************************************************************************** * CONSTANTS ******************************************************************************/ @@ -146,7 +156,7 @@ #define AIOT_CONFIG_LPWAN_UPDATE_RETRY_DELAY_ms (10000UL) #endif -#if defined(HAS_TCP) +#if defined(USE_NOTECARD) || defined(HAS_TCP) #define AIOT_CONFIG_RECONNECTION_RETRY_DELAY_ms (1000UL) #define AIOT_CONFIG_MAX_RECONNECTION_RETRY_DELAY_ms (32000UL) diff --git a/src/ArduinoIoTCloud.h b/src/ArduinoIoTCloud.h index 7c0bcc5f..cd7254ed 100644 --- a/src/ArduinoIoTCloud.h +++ b/src/ArduinoIoTCloud.h @@ -161,7 +161,9 @@ class ArduinoIoTCloudClass OnCloudEventCallback _cloud_event_callback[3]; }; -#ifdef HAS_TCP +#if defined(USE_NOTECARD) + #include "ArduinoIoTCloudNotecard.h" +#elif defined(HAS_TCP) #include "ArduinoIoTCloudTCP.h" #elif defined(HAS_LORA) #include "ArduinoIoTCloudLPWAN.h" diff --git a/src/ArduinoIoTCloudDevice.cpp b/src/ArduinoIoTCloudDevice.cpp index cfef518e..889a627e 100644 --- a/src/ArduinoIoTCloudDevice.cpp +++ b/src/ArduinoIoTCloudDevice.cpp @@ -14,7 +14,7 @@ #include -#ifdef HAS_TCP +#if defined(USE_NOTECARD) || defined(HAS_TCP) #include "ArduinoIoTCloudDevice.h" #include "interfaces/CloudProcess.h" @@ -146,4 +146,4 @@ ArduinoCloudDevice::State ArduinoCloudDevice::handleDisconnected() { return State::Disconnected; } -#endif /* HAS_TCP */ +#endif /* USE_NOTECARD || HAS_TCP */ diff --git a/src/ArduinoIoTCloudNotecard.cpp b/src/ArduinoIoTCloudNotecard.cpp new file mode 100644 index 00000000..267dfb5e --- /dev/null +++ b/src/ArduinoIoTCloudNotecard.cpp @@ -0,0 +1,552 @@ +/* + This file is part of ArduinoIoTCloud. + + Copyright 2019 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 "AIoTC_Config.h" + +#if defined(USE_NOTECARD) + +#include "ArduinoIoTCloudNotecard.h" + +#include +#include + +#include + +#include "cbor/CBOREncoder.h" +#include "cbor/MessageDecoder.h" +#include "cbor/MessageEncoder.h" + +#if OTA_ENABLED +#include "ota/OTA.h" +#endif /* OTA_ENABLED */ + +/****************************************************************************** + * CONSTANTS + ******************************************************************************/ + +static size_t const CBOR_NOTE_MSG_MAX_SIZE = 255; +static size_t const POLL_INTERVAL_MS = 10000; + +/****************************************************************************** + * LOCAL MODULE FUNCTIONS + ******************************************************************************/ + +unsigned long getTime() +{ + return ArduinoCloud.getInternalTime(); +} + +void ISR_dataAvailable(void) +{ + ArduinoCloud._data_available = true; +} + +/****************************************************************************** + * CTOR/DTOR + ******************************************************************************/ + +ArduinoIoTCloudNotecard::ArduinoIoTCloudNotecard() +: + _state{State::ConnectPhy} + ,_connection_attempt(0,0) + ,_message_stream(std::bind(&ArduinoIoTCloudNotecard::sendMessage, this, std::placeholders::_1)) + ,_thing(&_message_stream) + ,_device(&_message_stream) + ,_last_poll_ms{0} + ,_interrupt_pin{-1} + ,_data_available{false} +#if defined(BOARD_HAS_SECRET_KEY) + ,_secret_device_key{""} +#endif /* BOARD_HAS_SECRET_KEY */ +#if OTA_ENABLED + ,_ota_cap{false} + ,_ota_error{static_cast(OTAError::None)} + ,_ota_img_sha256{"Inv."} + ,_ota_url{""} + ,_ota_req{false} + ,_ask_user_before_executing_ota{false} + ,_get_ota_confirmation{nullptr} +#endif /* OTA_ENABLED */ +{ + +} + +/****************************************************************************** + * PUBLIC MEMBER FUNCTIONS + ******************************************************************************/ + +int ArduinoIoTCloudNotecard::begin(ConnectionHandler &connection, int interrupt_pin) +{ + _connection = &connection; + if (NetworkConnectionState::ERROR == _connection->check()) { + DEBUG_ERROR("ArduinoIoTCloudNotecard::%s encountered fatal connection error!", __FUNCTION__); + return 0; // (false -> failure) + } + +#ifdef BOARD_HAS_SECRET_KEY + // Update Device ID using connection cache + setBoardId(getDeviceId()); +#endif + + // Configure the interrupt pin + if (interrupt_pin >= 0) { + ::pinMode(interrupt_pin, INPUT); + ::attachInterrupt(digitalPinToInterrupt(interrupt_pin), ISR_dataAvailable, RISING); + _interrupt_pin = interrupt_pin; + } + +#if OTA_ENABLED + /* Setup OTA TLS client */ + _otaClient.begin(connection); +#endif + + // Begin the Notecard time service + _time_service.begin(&connection); + + /* Setup retry timers */ + _connection_attempt.begin(AIOT_CONFIG_RECONNECTION_RETRY_DELAY_ms, AIOT_CONFIG_MAX_RECONNECTION_RETRY_DELAY_ms); + + // Configure the Device and Thing property containers + _thing.begin(); + _device.begin(); + + return 1; // (true -> success) +} + +int ArduinoIoTCloudNotecard::connected() +{ + return (_connection->check() == NetworkConnectionState::CONNECTED); +} + +void ArduinoIoTCloudNotecard::printDebugInfo() +{ + // Print the debug information + NetworkConnectionState conn_state = _connection->check(); + DEBUG_INFO("***** Arduino IoT Cloud Notecard - configuration info *****"); + DEBUG_INFO("Notecard UID: %s", reinterpret_cast(_connection)->getNotecardUid().c_str()); + DEBUG_INFO("Arduino Device ID: %s", getDeviceId().c_str()); + if (NetworkConnectionState::CONNECTED == conn_state) + { + DEBUG_INFO("Arduino Thing ID: %s", getThingId().c_str()); + } + else + { + DEBUG_INFO("Arduino Thing ID: awaiting connection..."); + } +} + +void ArduinoIoTCloudNotecard::update() +{ + /* Run through the state machine. */ + State next_state = _state; + switch (_state) + { + case State::ConnectPhy: next_state = handle_ConnectPhy(); break; + case State::SyncTime: next_state = handle_SyncTime(); break; + case State::ConfigureNotehub: next_state = handle_ConfigureNotehub(); break; + case State::Connected: next_state = handle_Connected(); break; + case State::Disconnect: next_state = handle_Disconnect(); break; + } + _state = next_state; + +#if OTA_ENABLED + if (State::Connected == _state) { + checkOTARequest(); + } +#endif /* OTA_ENABLED */ +} + +/****************************************************************************** + * PRIVATE STATE MACHINE FUNCTIONS + ******************************************************************************/ + +ArduinoIoTCloudNotecard::State ArduinoIoTCloudNotecard::handle_ConnectPhy() +{ + if (_connection->check() == NetworkConnectionState::CONNECTED + && (!_connection_attempt.isRetry() || (_connection_attempt.isRetry() && _connection_attempt.isExpired()))) + return State::SyncTime; + else + return State::ConnectPhy; +} + +ArduinoIoTCloudNotecard::State ArduinoIoTCloudNotecard::handle_SyncTime() +{ + const uint32_t current_time = ArduinoCloud.getInternalTime(); + if (TimeServiceClass::isTimeValid(current_time)) + { + DEBUG_VERBOSE("ArduinoIoTCloudNotecard::%s internal clock configured to posix timestamp %d", __FUNCTION__, current_time); + return State::ConfigureNotehub; + } + + DEBUG_ERROR("ArduinoIoTCloudNotecard::%s could not get valid time. Retrying now.", __FUNCTION__); + return State::ConnectPhy; +} + +ArduinoIoTCloudNotecard::State ArduinoIoTCloudNotecard::handle_ConfigureNotehub() +{ + if (!connected()) + { + DEBUG_ERROR("ArduinoIoTCloudNotecard::%s connection to Notehub lost", __FUNCTION__); + return State::ConnectPhy; + } + +#if defined(BOARD_HAS_SECRET_KEY) + if (reinterpret_cast(_connection)->syncSecretDeviceKey(_secret_device_key)) { + DEBUG_WARNING("ArduinoIoTCloudNotecard::%s failed to set secret device key", __FUNCTION__); + DEBUG_WARNING("You may manually enter the secret key on Notehub as a device level environment variable named `arduino_iot_cloud_secret_device_key`"); + } +#endif + + return State::Connected; +} + +ArduinoIoTCloudNotecard::State ArduinoIoTCloudNotecard::handle_Connected() +{ + if (!connected() || !_thing.connected() || !_device.connected()) + { + return State::Disconnect; + } + + //TODO: Understand how available applies to the _device.update() and _thing.update() + /* Poll Notecard for new messages */ + pollNotecard(); + + /* Call CloudDevice process to get configuration */ + _device.update(); + +#if OTA_ENABLED + if(_get_ota_confirmation != nullptr && + _ota.getState() == OTACloudProcessInterface::State::OtaAvailable && + _get_ota_confirmation()) { + _ota.approveOta(); + } + + _ota.update(); +#endif // OTA_ENABLED + + + if (_device.isAttached()) { + /* Call CloudThing process to synchronize properties */ + _thing.update(); + } + + return State::Connected; +} + +ArduinoIoTCloudNotecard::State ArduinoIoTCloudNotecard::handle_Disconnect() +{ + if (!connected()) { + DEBUG_ERROR("ArduinoIoTCloudNotecard::%s connection to Notehub lost", __FUNCTION__); + } + + // Reset the Thing and Device property containers + Message message = { ResetCmdId }; + _thing.handleMessage(&message); + _device.handleMessage(&message); + + DEBUG_INFO("Disconnected from Arduino IoT Cloud"); + + // Execute the user-defined disconnect callback + execCloudEventCallback(ArduinoIoTCloudEvent::DISCONNECT); + + /* Setup timer for broker connection and restart */ + _connection_attempt.begin(AIOT_CONFIG_RECONNECTION_RETRY_DELAY_ms, AIOT_CONFIG_MAX_RECONNECTION_RETRY_DELAY_ms); + return State::ConnectPhy; +} + +/****************************************************************************** + * PRIVATE SUPPORT FUNCTIONS + ******************************************************************************/ + +void ArduinoIoTCloudNotecard::attachThing(String thingId) +{ + _thing_id = thingId; + + Message message; + message = { DeviceAttachedCmdId }; + _device.handleMessage(&message); + + DEBUG_INFO("Connected to Arduino IoT Cloud"); + DEBUG_INFO("Thing ID: %s", getThingId().c_str()); + execCloudEventCallback(ArduinoIoTCloudEvent::CONNECT); +} + +bool ArduinoIoTCloudNotecard::available(void) +{ + bool result; + + const bool interrupts_enabled = (_interrupt_pin >= 0); + bool check_data = true; + if (interrupts_enabled) { + check_data = (_data_available || ((::millis() - _last_poll_ms) > POLL_INTERVAL_MS)); + } + + if (check_data) { + result = _connection->available(); + _data_available = ::digitalRead(_interrupt_pin); + _last_poll_ms = ::millis(); + } else { + result = false; + } + + return result; +} + +#if OTA_ENABLED +void ArduinoIoTCloudNotecard::checkOTARequest(void) { + /* Request a OTA download if the hidden property + * OTA request has been set. + */ + + if (_ota_req) + { + bool const ota_execution_allowed_by_user = (_get_ota_confirmation != nullptr && _get_ota_confirmation()); + bool const perform_ota_now = ota_execution_allowed_by_user || !_ask_user_before_executing_ota; + if (perform_ota_now) { + /* Clear the error flag. */ + _ota_error = static_cast(OTAError::None); + _ota_error = 0; + /* Clear the request flag. */ + _ota_req = false; + /* Transmit the cleared request flags to the cloud. */ + sendDevicePropertyToCloud("OTA_REQ"); + /* Call member function to handle OTA request. */ + _ota_error = OTA::onRequest(_ota_url, _connection->getInterface()); + DEBUG_WARNING("OTA request received. OTA is not currently supported by Notecard."); + /* If something fails send the OTA error to the cloud */ + sendDevicePropertyToCloud("OTA_ERROR"); + } + } + + /* Check if we have received the OTA_URL property and provide + * echo to the cloud. + */ + sendDevicePropertyToCloud("OTA_URL"); +} +#endif /* OTA_ENABLED */ + +void ArduinoIoTCloudNotecard::detachThing() +{ + Message message; + message = { DeviceDetachedCmdId }; + _device.handleMessage(&message); + + _thing_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"; + DEBUG_INFO("Disconnected from Arduino IoT Cloud"); + execCloudEventCallback(ArduinoIoTCloudEvent::DISCONNECT); +} + +void ArduinoIoTCloudNotecard::fetchIncomingBytes(uint8_t *buf, size_t &len) +{ + size_t bytes_received = 0; + for (; + _connection->available() && (bytes_received < len); + ++bytes_received) + { + buf[bytes_received] = _connection->read(); + } + len = bytes_received; +} + +void ArduinoIoTCloudNotecard::pollNotecard(void) +{ + /* Decode available data. */ + if (available()) { + size_t note_len = CBOR_NOTE_MSG_MAX_SIZE; + uint8_t note_buf[CBOR_NOTE_MSG_MAX_SIZE]; + fetchIncomingBytes(note_buf, note_len); + processMessage(note_buf, note_len); + } +} + +void ArduinoIoTCloudNotecard::processCommand(const uint8_t *buf, size_t len) +{ + CommandDown command; + DEBUG_VERBOSE("ArduinoIoTCloudNotecard::%s [%d] received %d bytes", __FUNCTION__, millis(), len); + CBORMessageDecoder decoder; + + if (decoder.decode((Message*)&command, buf, len) != Decoder::Status::Error) { + DEBUG_VERBOSE("ArduinoIoTCloudNotecard::%s [%d] received command id %d", __FUNCTION__, millis(), command.c.id); + switch (command.c.id) + { + case CommandId::ThingUpdateCmdId: + { + DEBUG_VERBOSE("ArduinoIoTCloudNotecard::%s [%d] device configuration received", __FUNCTION__, millis()); + String new_thing_id = String(command.thingUpdateCmd.params.thing_id); + + if (!new_thing_id.length()) { + /* Send message to device state machine to inform we have received a null thing-id */ + _thing_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"; + Message message; + message = { DeviceRegisteredCmdId }; + _device.handleMessage(&message); + } else { + if (_device.isAttached() && _thing_id != new_thing_id) { + detachThing(); + } + if (!_device.isAttached()) { + attachThing(new_thing_id); + } + } + } + break; + + case CommandId::ThingDetachCmdId: + { + if (!_device.isAttached() || _thing_id != String(command.thingDetachCmd.params.thing_id)) { + DEBUG_VERBOSE("ArduinoIoTCloudNotecard::%s [%d] thing detach rejected", __FUNCTION__, millis()); + } + + DEBUG_VERBOSE("ArduinoIoTCloudNotecard::%s [%d] thing detach received", __FUNCTION__, millis()); + detachThing(); + } + break; + + case CommandId::TimezoneCommandDownId: + { + DEBUG_VERBOSE("ArduinoIoTCloudNotecard::%s [%d] timezone update received", __FUNCTION__, millis()); + _thing.handleMessage((Message*)&command); + } + break; + + case CommandId::LastValuesUpdateCmdId: + { + DEBUG_VERBOSE("ArduinoIoTCloudNotecard::%s [%d] last values received", __FUNCTION__, millis()); + CBORDecoder::decode(_thing.getPropertyContainer(), + (uint8_t*)command.lastValuesUpdateCmd.params.last_values, + command.lastValuesUpdateCmd.params.length, true); + _thing.handleMessage((Message*)&command); + execCloudEventCallback(ArduinoIoTCloudEvent::SYNC); + + /* + * NOTE: in this current version properties are not properly integrated with the new paradigm of + * modeling the messages with C structs. The current CBOR library allocates an array in the heap + * thus we need to delete it after decoding it with the old CBORDecoder + */ + free(command.lastValuesUpdateCmd.params.last_values); + } + break; + +#if OTA_ENABLED + case CommandId::OtaUpdateCmdDownId: + { + DEBUG_VERBOSE("ArduinoIoTCloudNotecard::%s [%d] ota update received", __FUNCTION__, millis()); + _ota.handleMessage((Message*)&command); + } +#endif + + default: + break; + } + } +} + +void ArduinoIoTCloudNotecard::processMessage(const uint8_t *buf, size_t len) +{ + DEBUG_VERBOSE("Received %d bytes from cloud. Decoding...", len); + NotecardConnectionHandler *notecard_connection = reinterpret_cast(_connection); + switch (notecard_connection->getTopicType()) { + // Commands + case NotecardConnectionHandler::TopicType::Command: + processCommand(buf, len); + break; + // Telemetry + case NotecardConnectionHandler::TopicType::Thing: + CBORDecoder::decode(_thing.getPropertyContainer(), buf, len); + break; + // Notehub Diagnostic + case NotecardConnectionHandler::TopicType::Notehub: + { + char *diag_msg = reinterpret_cast(const_cast(buf)); + diag_msg[len - 1] = '\0'; // Ensure null-termination + DEBUG_WARNING("Notehub diagnostic message: %s", diag_msg); + } + break; + default: + DEBUG_WARNING("Unable to decode unknown topic type: 0x%2X", notecard_connection->getTopicType()); + break; + } +} + +void ArduinoIoTCloudNotecard::requestThingIdFromNotehub(void) +{ + NotecardConnectionHandler *notecard_connection = reinterpret_cast(_connection); + + notecard_connection->setTopicType(NotecardConnectionHandler::TopicType::Notehub); + notecard_connection->write(nullptr, 0); +} + +void ArduinoIoTCloudNotecard::sendMessage(Message * msg) +{ + switch (msg->id) { + case PropertiesUpdateCmdId: + return sendThingPropertyContainerToCloud(); + break; + + default: + sendCommandMsgToCloud(msg); + break; + } +} + +void ArduinoIoTCloudNotecard::sendCommandMsgToCloud(Message * msg_) +{ + size_t bytes_encoded = CBOR_NOTE_MSG_MAX_SIZE; + uint8_t data[CBOR_NOTE_MSG_MAX_SIZE]; + CBORMessageEncoder encoder; + NotecardConnectionHandler *notecard_connection = reinterpret_cast(_connection); + + if (encoder.encode(msg_, data, bytes_encoded) == Encoder::Status::Complete) { + if (bytes_encoded > 0) { + notecard_connection->setTopicType(NotecardConnectionHandler::TopicType::Command); + notecard_connection->write(data, bytes_encoded); + } + DEBUG_DEBUG("Encoded %d bytes for Command Message", bytes_encoded); + } else { + DEBUG_ERROR("Failed to encode Command Message"); + } +} + +void ArduinoIoTCloudNotecard::sendThingPropertyContainerToCloud() +{ + int bytes_encoded = 0; + uint8_t data[CBOR_NOTE_MSG_MAX_SIZE]; + NotecardConnectionHandler *notecard_connection = reinterpret_cast(_connection); + + // Check if any property needs encoding and send them to the cloud + if (CBOREncoder::encode(_thing.getPropertyContainer(), data, sizeof(data), bytes_encoded, _thing.getPropertyContainerIndex(), USE_LIGHT_PAYLOADS) == CborNoError) { + if (bytes_encoded > 0) { + notecard_connection->setTopicType(NotecardConnectionHandler::TopicType::Thing); + notecard_connection->write(data, bytes_encoded); + DEBUG_DEBUG("Encoded %d bytes for Thing properties", bytes_encoded); + } + } else { + DEBUG_ERROR("Failed to encode Thing properties"); + } +} + +/****************************************************************************** + * EXTERN DEFINITION + ******************************************************************************/ + +ArduinoIoTCloudNotecard ArduinoCloud; + +#endif // USE_NOTECARD diff --git a/src/ArduinoIoTCloudNotecard.h b/src/ArduinoIoTCloudNotecard.h new file mode 100644 index 00000000..6709b7ff --- /dev/null +++ b/src/ArduinoIoTCloudNotecard.h @@ -0,0 +1,136 @@ +/* + This file is part of ArduinoIoTCloud. + + Copyright 2024 Blues (http://www.blues.com/) + + 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_IOT_CLOUD_NOTECARD_H +#define ARDUINO_IOT_CLOUD_NOTECARD_H + +/****************************************************************************** + * INCLUDE + ******************************************************************************/ + +#include "ArduinoIoTCloud.h" +#include "ArduinoIoTCloudThing.h" +#include "ArduinoIoTCloudDevice.h" + +/****************************************************************************** + * DEFINES + ******************************************************************************/ + +#define USE_LIGHT_PAYLOADS (false) + +/****************************************************************************** + * CONSTANTS + ******************************************************************************/ + +/****************************************************************************** + * TYPEDEF + ******************************************************************************/ + +#if OTA_ENABLED +typedef bool (*onOTARequestCallbackFunc)(void); +#endif /* OTA_ENABLED */ + +/****************************************************************************** + * CLASS DECLARATION + ******************************************************************************/ + +class ArduinoIoTCloudNotecard : public ArduinoIoTCloudClass +{ + public: + ArduinoIoTCloudNotecard(); + virtual ~ArduinoIoTCloudNotecard() { } + + virtual void update () override; + virtual int connected () override; + virtual void printDebugInfo() override; + inline virtual PropertyContainer &getThingPropertyContainer() override { return _thing.getPropertyContainer(); } + + int begin(ConnectionHandler &connection, int interrupt_pin = -1); + +#ifdef BOARD_HAS_SECRET_KEY + inline void setBoardId (String const & device_id) { (_connection && (NetworkConnectionState::INIT != _connection->check())) ? setDeviceId(reinterpret_cast(_connection)->syncArduinoDeviceId(device_id)) : setDeviceId(device_id); } + inline void setSecretDeviceKey(String const & secret_device_key) { _secret_device_key = secret_device_key; } +#endif + + private: + + enum class State + { + ConnectPhy, + SyncTime, + ConfigureNotehub, + Connected, + Disconnect, + }; + + State _state; + TimedAttempt _connection_attempt; + MessageStream _message_stream; + ArduinoCloudThing _thing; + ArduinoCloudDevice _device; + + // Notecard member variables + uint32_t _last_poll_ms; + int _interrupt_pin; + volatile bool _data_available; + +#ifdef BOARD_HAS_SECRET_KEY + String _secret_device_key; +#endif + +#if OTA_ENABLED + // OTA member variables + bool _ota_cap; + int _ota_error; + String _ota_img_sha256; + String _ota_url; + bool _ota_req; + bool _ask_user_before_executing_ota; + onOTARequestCallbackFunc _get_ota_confirmation; +#endif /* OTA_ENABLED */ + + State handle_ConnectPhy(); + State handle_SyncTime(); + State handle_ConfigureNotehub(); + State handle_Connected(); + State handle_Disconnect(); + + void attachThing(String thingId); + bool available (void); +#if OTA_ENABLED + void checkOTARequest(void); +#endif /* OTA_ENABLED */ + void detachThing(); + void fetchIncomingBytes(uint8_t *buf, size_t &len); + void pollNotecard(void); + void processCommand(const uint8_t *buf, size_t len); + void processMessage(const uint8_t *buf, size_t len); + void requestThingIdFromNotehub(void); + void sendMessage(Message * msg); + void sendCommandMsgToCloud(Message * msg_); + void sendThingPropertyContainerToCloud(void); + + friend void ISR_dataAvailable (void); +}; + +/****************************************************************************** + * EXTERN DECLARATION + ******************************************************************************/ + +extern ArduinoIoTCloudNotecard ArduinoCloud; + +#endif diff --git a/src/ArduinoIoTCloudThing.cpp b/src/ArduinoIoTCloudThing.cpp index 98ebb0fb..d20c75dc 100644 --- a/src/ArduinoIoTCloudThing.cpp +++ b/src/ArduinoIoTCloudThing.cpp @@ -15,7 +15,7 @@ #include -#ifdef HAS_TCP +#if defined(USE_NOTECARD) || defined(HAS_TCP) #include "ArduinoIoTCloudThing.h" #include "interfaces/CloudProcess.h" @@ -180,4 +180,4 @@ ArduinoCloudThing::State ArduinoCloudThing::handleDisconnect() { return State::Disconnect; } -#endif /* HAS_TCP */ +#endif /* USE_NOTECARD || HAS_TCP */ diff --git a/src/utility/time/RTCMillis.cpp b/src/utility/time/RTCMillis.cpp index 419236d1..63d6c44e 100644 --- a/src/utility/time/RTCMillis.cpp +++ b/src/utility/time/RTCMillis.cpp @@ -15,12 +15,14 @@ a commercial license, send an email to license@arduino.cc. */ -#ifdef ARDUINO_ARCH_ESP8266 - /************************************************************************************** * INCLUDE **************************************************************************************/ +#include "AIoTC_Config.h" + +#if defined(USE_NOTECARD) || defined(ARDUINO_ARCH_ESP8266) + #include #include "RTCMillis.h" @@ -59,4 +61,4 @@ unsigned long RTCMillis::get() return _last_rtc_update_value; } -#endif /* ARDUINO_ARCH_ESP8266 */ +#endif /* USE_NOTECARD || ARDUINO_ARCH_ESP8266 */ diff --git a/src/utility/time/RTCMillis.h b/src/utility/time/RTCMillis.h index 1fa7e0f4..f27b4bc5 100644 --- a/src/utility/time/RTCMillis.h +++ b/src/utility/time/RTCMillis.h @@ -18,7 +18,7 @@ #ifndef ARDUINO_IOT_CLOUD_RTC_MILLIS_H_ #define ARDUINO_IOT_CLOUD_RTC_MILLIS_H_ -#ifdef ARDUINO_ARCH_ESP8266 +#if defined(USE_NOTECARD) || defined(ARDUINO_ARCH_ESP8266) /************************************************************************************** * INCLUDE @@ -45,6 +45,6 @@ class RTCMillis }; -#endif /* ARDUINO_ARCH_ESP8266 */ +#endif /* USE_NOTECARD || ARDUINO_ARCH_ESP8266 */ #endif /* ARDUINO_IOT_CLOUD_RTC_MILLIS_H_ */ diff --git a/src/utility/time/TimeService.cpp b/src/utility/time/TimeService.cpp index 5bf081de..992f228e 100644 --- a/src/utility/time/TimeService.cpp +++ b/src/utility/time/TimeService.cpp @@ -19,26 +19,21 @@ * INCLUDE **************************************************************************************/ -#include #include -#include "TimeService.h" -#include "NTPUtils.h" + +#include "AIoTC_Config.h" #include "AIoTC_Const.h" +#include "NTPUtils.h" +#include "TimeService.h" -#ifdef ARDUINO_ARCH_SAMD +#if defined(USE_NOTECARD) || defined(ARDUINO_ARCH_ESP8266) + #include "RTCMillis.h" +#elif defined(ARDUINO_ARCH_SAMD) #include -#endif - -#ifdef ARDUINO_ARCH_MBED +#elif defined(ARDUINO_ARCH_MBED) #include -#endif - -#ifdef ARDUINO_ARCH_ESP8266 - #include "RTCMillis.h" -#endif - -#ifdef ARDUINO_ARCH_RENESAS +#elif defined(ARDUINO_ARCH_RENESAS) #include "RTC.h" #endif @@ -46,12 +41,10 @@ * GLOBAL VARIABLES **************************************************************************************/ -#ifdef ARDUINO_ARCH_SAMD -RTCZero rtc; -#endif - -#ifdef ARDUINO_ARCH_ESP8266 +#if defined(USE_NOTECARD) || defined(ARDUINO_ARCH_ESP8266) RTCMillis rtc; +#elif defined(ARDUINO_ARCH_SAMD) +RTCZero rtc; #endif /************************************************************************************** @@ -60,6 +53,12 @@ RTCMillis rtc; time_t cvt_time(char const * time); +#if defined(USE_NOTECARD) +void notecard_initRTC(); +void notecard_setRTC(unsigned long time); +unsigned long notecard_getRTC(); +#else + #ifdef ARDUINO_ARCH_SAMD void samd_initRTC(); void samd_setRTC(unsigned long time); @@ -90,6 +89,8 @@ void renesas_setRTC(unsigned long time); unsigned long renesas_getRTC(); #endif +#endif /* USE_NOTECARD */ + /************************************************************************************** * DEFINES **************************************************************************************/ @@ -161,10 +162,9 @@ bool TimeServiceClass::sync() if(_sync_func) { utc = _sync_func(); } else { -#ifdef HAS_TCP +#if defined(USE_NOTECARD) || defined(HAS_TCP) utc = getRemoteTime(); -#endif -#ifdef HAS_LORA +#elif defined(HAS_LORA) /* Just keep incrementing stored RTC value*/ utc = getRTC(); #endif @@ -275,7 +275,7 @@ unsigned long TimeServiceClass::getTimeFromString(const String& input) * PRIVATE MEMBER FUNCTIONS **************************************************************************************/ -#ifdef HAS_TCP +#if defined(USE_NOTECARD) || defined(HAS_TCP) bool TimeServiceClass::connected() { if(_con_hdl == nullptr) { @@ -288,6 +288,7 @@ bool TimeServiceClass::connected() unsigned long TimeServiceClass::getRemoteTime() { if(connected()) { +#ifdef HAS_TCP /* At first try to obtain a valid time via NTP. * This is the most reliable time source and it will * ensure a correct behaviour of the library. @@ -298,6 +299,7 @@ unsigned long TimeServiceClass::getRemoteTime() return ntp_time; } } +#endif /* HAS_TCP */ /* As fallback if NTP request fails try to obtain the * network time using the connection handler. @@ -316,7 +318,7 @@ unsigned long TimeServiceClass::getRemoteTime() return EPOCH_AT_COMPILE_TIME; } -#endif /* HAS_TCP */ +#endif /* USE_NOTECARD || HAS_TCP */ bool TimeServiceClass::isTimeValid(unsigned long const time) { @@ -331,7 +333,9 @@ bool TimeServiceClass::isTimeZoneOffsetValid(long const offset) void TimeServiceClass::initRTC() { -#if defined (ARDUINO_ARCH_SAMD) +#if defined (USE_NOTECARD) + notecard_initRTC(); +#elif defined (ARDUINO_ARCH_SAMD) samd_initRTC(); #elif defined (ARDUINO_ARCH_MBED) mbed_initRTC(); @@ -348,7 +352,9 @@ void TimeServiceClass::initRTC() void TimeServiceClass::setRTC(unsigned long time) { -#if defined (ARDUINO_ARCH_SAMD) +#if defined (USE_NOTECARD) + notecard_setRTC(time); +#elif defined (ARDUINO_ARCH_SAMD) samd_setRTC(time); #elif defined (ARDUINO_ARCH_MBED) mbed_setRTC(time); @@ -365,7 +371,9 @@ void TimeServiceClass::setRTC(unsigned long time) unsigned long TimeServiceClass::getRTC() { -#if defined (ARDUINO_ARCH_SAMD) +#if defined (USE_NOTECARD) + return notecard_getRTC(); +#elif defined (ARDUINO_ARCH_SAMD) return samd_getRTC(); #elif defined (ARDUINO_ARCH_MBED) return mbed_getRTC(); @@ -420,6 +428,23 @@ time_t cvt_time(char const * time) return build_time; } +#ifdef USE_NOTECARD +void notecard_initRTC() +{ + rtc.begin(); +} + +void notecard_setRTC(unsigned long time) +{ + rtc.set(time); +} + +unsigned long notecard_getRTC() +{ + return rtc.get(); +} +#else + #ifdef ARDUINO_ARCH_SAMD void samd_initRTC() { @@ -509,6 +534,8 @@ unsigned long renesas_getRTC() } #endif +#endif /* USE_NOTECARD */ + /****************************************************************************** * EXTERN DEFINITION ******************************************************************************/ diff --git a/src/utility/time/TimeService.h b/src/utility/time/TimeService.h index 794ec344..d9da1dd1 100644 --- a/src/utility/time/TimeService.h +++ b/src/utility/time/TimeService.h @@ -69,7 +69,7 @@ class TimeServiceClass unsigned long _sync_interval_ms; syncTimeFunctionPtr _sync_func; -#ifdef HAS_TCP +#if defined(USE_NOTECARD) || defined(HAS_TCP) unsigned long getRemoteTime(); bool connected(); #endif