Skip to content

Commit

Permalink
Merge pull request #20 from DatavenueLiveObjects/update
Browse files Browse the repository at this point in the history
Update package
  • Loading branch information
DatavenueLiveObjects authored Jan 16, 2025
2 parents 919d489 + 65698f0 commit ac0c1c7
Show file tree
Hide file tree
Showing 56 changed files with 954 additions and 53 deletions.
15 changes: 7 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
# Prototype with Orange using Live Objects and Arduino MKR Boards
# Quickly prototype IoT solutions with Orange using Live Objects and Arduino compatible boards

### Discover Orange [**Live Objects**](https://liveobjects.orange-business.com) using dedicated SDK for [**Arduino MKR family boards**](https://store.arduino.cc/arduino-genuino/arduino-genuino-mkr-family).
### Discover [**Live Objects**](https://liveobjects.orange-business.com), the IoT platform from Orange using this dedicated SDK for [**Arduino**](https://store.arduino.cc/arduino-genuino/arduino-genuino-mkr-family) and compatible boards.

This code wraps all the functions necessary to make your object work with Live Objects.
This dedicated SDK simplifies connecting your MKR board to the Live Objects platform. It manages LTE-M, GSM, and WiFi connections (depending on your board) and handle MQTT(S) and SMS communication behind the scenes. Easily define parameters you can update remotely and create commands to trigger actions on your device.

You can declare parameters, which you can later update OTA from Live objects. You can also create commands to trigger actions remotely.

The code will manage the LTE-M, GSM and WiFi connection (depending on currently used board), as well MQTT(S) and SMS exchanges with Live objects under the hood to keep your parameters up to date or execute the commands received without you having to take care of them (apart from writing the code of these commands, of course).
Focus on your application logic – this library handles the communication with the Live Objects platform, keeping your parameters synchronized and executing received commands.

## Compatibility ##
| Board | MQTT | MQTTS | SMS |
Expand Down Expand Up @@ -36,7 +34,8 @@ This code needs external libraries to run, that you can install using the built-
- [PubSubClient](https://pubsubclient.knolleary.net/) library provides a client for doing simple publish/subscribe messaging with a server that supports MQTT

#### Library developed by Benoît Blanchon (mandatory for both Arduino, ESP and Adafruit boards)
- [ArduinoJson](https://arduinojson.org/), a powerful library used to parse, store and handle JSON easily
- [ArduinoJson](https://arduinojson.org/), a powerful library used to parse, store and handle JSON easily.
The default installation includes ArduinoJSON v6.21.5, optimized for the architectures supported by this SDK. While later versions of ArduinoJSON are compatible, they will consume more flash memory (see [here](https://arduinojson.org/news/2024/01/03/arduinojson-7/)).

#### SAMD21 Arduino core
- You also need to install the Arduino core for Atmel SAMD21 processor, used on the boards of the MKR family. Open the [Boards Manager](https://www.arduino.cc/en/guide/cores) and install the package called "Arduino SAMD Boards (32-bit ARM Cortex-M0+)".
Expand All @@ -47,7 +46,7 @@ This code needs external libraries to run, that you can install using the built-
2. Create an [API key](https://liveobjects.orange-business.com/#/administration/apikeys) for your device. Give it a name, select the *Device access* role and validate. Copy the key.
3. Clone or download the directory from Github.
4. In the **'src/arduino_secrets.h'** file :
- Paste it as initialization value for the `SECRET_LIVEOBJECTS_API_KEY` variable in the 'arduino_secrets.h' file -keep the double quotes!
- Paste it as initialization value for the `SECRET_LIVEOBJECTS_API_KEY` variable in the 'arduino_secrets.h' file keep the double quotes!

- In case of feather 32u4 you have to change type of this variable to *char** from *String*.
- Fill in the connection(WIFI or GSM) credentials if needed (pin code, APN information, etc). In case of GSM connection, most of the time, APN will set up automatically. Your SIM card may have a default pin code (like "0000"), unless you deactivated it using the [Pin management](https://github.com/arduino-libraries/MKRNB/blob/master/examples/Tools/PinManagement/PinManagement.ino) sketch, provided with the MKRNB library.
Expand Down
29 changes: 15 additions & 14 deletions keywords.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,32 +14,33 @@ enableDebug KEYWORD2
setClientID KEYWORD2
setDecoder KEYWORD2
setModel KEYWORD2
debugEnabled KEYWORD2
debugEnabled KEYWORD2
addTimestamp KEYWORD2
addLocation KEYWORD2
addNetworkInfo KEYWORD2
addTags KEYWORD2
addPowerStatus KEYWORD2
clearPayload KEYWORD2
publishMessage KEYWORD2
networkCheck KEYWORD2
addCommand KEYWORD2
addParameter KEYWORD2
addToPayload KEYWORD2
addObjectToPayload KEYWORD2
connect KEYWORD2
addParameter KEYWORD2
addToPayload KEYWORD2
addObjectToPayload KEYWORD2
connect KEYWORD2
disconnect KEYWORD2
sendData KEYWORD2
loop KEYWORD2
begin KEYWORD2
changeConfiguration KEYWORD2
loop KEYWORD2
begin KEYWORD2
changeConfiguration KEYWORD2


######################################
# Constants (LITERAL1)
######################################
NONE LITERAL1
TLS LITERAL1
SMS LITERAL1
MQTT LITERAL1
BINARY LITERAL1
TEXT LITERAL1
NONE LITERAL1
TLS LITERAL1
SMS LITERAL1
MQTT LITERAL1
BINARY LITERAL1
TEXT LITERAL1
8 changes: 4 additions & 4 deletions library.properties
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
name=LiveObjectsSDK
version=2.1.1
version=2.1.2
author=Orange
maintainer=Marc Delain <[email protected]>, Krzysztof Krzeslak <[email protected]>, Tomasz Malek <[email protected]>
sentence=A library that makes connection with Orange LiveObjects platform a breeze.
paragraph=Supports connection with LiveObjects platform in device mode, with the use of LTE, GSM or WifI connectivity.
sentence=A library that simplifies the integration of Arduino boards with Live Objects, the IoT platform from Orange.
paragraph=Upgrade your Arduino projects to IoT with this library, which allows you to easily connect your board to the Live Objects platform: send data, remotely modify execution parameters, or send commands to interact with your board.
category=Communication
url=https://github.com/DatavenueLiveObjects/LiveObjects_SDK_for_Arduino
architectures=*
includes=LiveObjects.h
depends=WiFiNINA,MKRNB,ArduinoJson,MKRGSM,WiFi101,PubSubClient,ArduinoMqttClient,SparkFun VL6180 Sensor
depends=WiFiNINA,MKRNB,ArduinoJson(=6.21.5),MKRGSM,WiFi101,PubSubClient,ArduinoMqttClient,SparkFun VL6180 Sensor
19 changes: 13 additions & 6 deletions src/LiveObjectsBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ LiveObjectsBase::LiveObjectsBase()
lastKeepAliveNetwork(5000)
,m_sPayload()
,m_sDecoder()
,m_sModel("Orange")
,m_sModel(F(SW_MODEL))
,m_Security(NONE)
,m_bDebug(false)
,m_bInitialized(false)
Expand All @@ -31,12 +31,12 @@ void LiveObjectsBase::paramTyper(const String& name, bool* variable, LiveObjects
else
addTypedParam(name, variable, type, T_BOOL, callback);
}
void LiveObjectsBase::paramTyper(const String& name, char* variable, LiveObjects_parameterType type, onParameterUpdateCallback callback) {
/*void LiveObjectsBase::paramTyper(const String& name, char* variable, LiveObjects_parameterType type, onParameterUpdateCallback callback) {
if (type == IMPLICIT)
addTypedParam(name, variable, INTEGER, T_CHAR, callback);
else
addTypedParam(name, variable, type, T_CHAR, callback);
}
}*/
#if not defined ESP8266 && not defined ESP32 && not defined ARDUINO_AVR_FEATHER32U4
void LiveObjectsBase::paramTyper(const String& name, int* variable, LiveObjects_parameterType type, onParameterUpdateCallback callback) {
if (type == IMPLICIT)
Expand Down Expand Up @@ -111,9 +111,9 @@ void LiveObjectsBase::ptrTyper(const LiveObjects_parameter param, const JsonDocu
case T_BOOL:
updateParameter(param, (bool*)param.value, configIn, configOut);
break;
case T_CHAR:
/* case T_CHAR:
updateParameter(param, (char*)param.value, configIn, configOut);
break;
break;*/
#ifndef ESP8266
case T_INT:
updateParameter(param, (int*)param.value, configIn, configOut);
Expand Down Expand Up @@ -301,7 +301,7 @@ void LiveObjectsBase::sendData(const String customPayload) {
{
StaticJsonDocument<PAYLOAD_DATA_SIZE> payload;
deserializeJson(payload, customPayload);
if (!payload.containsKey(JSONMODEL)) payload[JSONMODEL] = m_sModel;
if (!payload[JSONMODEL].is<const char*>()) payload[JSONMODEL] = m_sModel;
publishMessage(m_sTopic, payload);
}
else publishMessage(m_sTopic, const_cast<String&>(customPayload));
Expand Down Expand Up @@ -425,6 +425,13 @@ void LiveObjectsBase::addLocation(double lat, double lon, double alt)
else addToStringPayload(lat,lon,alt);
}

void LiveObjectsBase::addTag(const char* tag)
{
if (!easyDataPayload[JSONTAGS].is<JsonArray>())
tags = easyDataPayload.createNestedArray(JSONTAGS);
tags.add(tag);
}

void LiveObjectsBase::clearPayload()
{
easyDataPayload.clear();
Expand Down
16 changes: 10 additions & 6 deletions src/LiveObjectsBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
******************************************************************************/
#define PAYLOAD_DATA_SIZE 1024
#define KEEP_ALIVE_NETWORK 1000
#define SW_REVISION "2.1.1"

#define SW_MODEL "LO_SDK_Arduino"
#define SW_REVISION "2.1.2"

/******************************************************************************
LiveObjects MQTT constants
Expand All @@ -24,7 +24,7 @@
#else
#define MQTT_BROKER "liveobjects.orange-business.com"
#endif
#define SDK_PREFIX "urn:lo:nsid:Arduino:"
#define SDK_PREFIX SW_MODEL ":"
#define MQTT_USER "json+device"
#define MQTT_PUBDATA "dev/data"
#define MQTT_PUBDATA_BINARY "dev/v1/data/binary"
Expand All @@ -42,6 +42,8 @@
#define JSONCFGTYPE "t"
#define JSONMODEL "model"
#define JSONVALUE "value"
#define JSONTAGS "tags"

/******************************************************************************
INCLUDES
******************************************************************************/
Expand Down Expand Up @@ -176,6 +178,7 @@ class LiveObjectsBase
public:
void addTimestamp(time_t timestamp);
void addLocation(double lat, double lon, double alt);
void addTag(const char* tag);
virtual void addPowerStatus()=0;
virtual void addNetworkInfo()=0;
void clearPayload();
Expand Down Expand Up @@ -215,7 +218,6 @@ class LiveObjectsBase
virtual void sendMQTT(String& topic, String& doc)=0;
virtual void deserializeMessage(JsonDocument& doc)=0;


protected:
/******************************************************************************
CONFIGURATION MANAGER
Expand Down Expand Up @@ -260,6 +262,8 @@ class LiveObjectsBase
LinkedList<LiveObjects_parameter> parameters;
LiveObjects_networkStatus networkStatus = DISCONNECTED;
StaticJsonDocument<PAYLOAD_DATA_SIZE> easyDataPayload;
JsonArray tags;

/******************************************************************************
VARIABLES
******************************************************************************/
Expand All @@ -285,12 +289,12 @@ class LiveObjectsBase
PARAM TYPERS
******************************************************************************/
void paramTyper(const String& name, bool* variable, LiveObjects_parameterType type, onParameterUpdateCallback callback);
void paramTyper(const String& name, char* variable, LiveObjects_parameterType type, onParameterUpdateCallback callback);
// void paramTyper(const String& name, char* variable, LiveObjects_parameterType type, onParameterUpdateCallback callback);
#if not defined ESP8266 && not defined ESP32 && not defined ARDUINO_AVR_FEATHER32U4
void paramTyper(const String& name, int* variable, LiveObjects_parameterType type, onParameterUpdateCallback callback);
void paramTyper(const String& name, unsigned int* variable, LiveObjects_parameterType type, onParameterUpdateCallback callback);
#endif
void paramTyper(const String& name, int8_t*variable, LiveObjects_parameterType type, onParameterUpdateCallback callback);
void paramTyper(const String& name, int8_t* variable, LiveObjects_parameterType type, onParameterUpdateCallback callback);
void paramTyper(const String& name, int32_t* variable, LiveObjects_parameterType type, onParameterUpdateCallback callback);
void paramTyper(const String& name, int16_t* variable, LiveObjects_parameterType type, onParameterUpdateCallback callback);
void paramTyper(const String& name, uint8_t* variable, LiveObjects_parameterType type, onParameterUpdateCallback callback);
Expand Down
2 changes: 1 addition & 1 deletion src/LiveObjectsCellular.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ void LiveObjectsCellular::connectNetwork()
#endif
if(modem.begin())
{
String imei="";
String imei="imei:";
for(int i=1;i<=3;i++)
{
imei=modem.getIMEI();
Expand Down
28 changes: 14 additions & 14 deletions src/LiveObjectsWiFi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ void LiveObjectsWiFi::begin(Protocol p, Encoding s, bool bDebug)
void LiveObjectsWiFi::connectNetwork()
{
#ifdef ADAFRUIT_FEATHER_M0
WiFi.setPins(8,7,4,2);
WiFi.setPins(8,7,4,2);
#endif
if(!m_bInitialized)
{
Expand Down Expand Up @@ -81,15 +81,17 @@ void LiveObjectsWiFi::connectNetwork()
outputDebug(TXT,".");
delay(1000);
}
outputDebug();
outputDebug();
IPAddress ip = WiFi.localIP();
for(int i=0;i<4;++i)
{
m_sIP+=ip[i];
if(i!=3) m_sIP+='.';
}

uint8_t mac[6];
m_sMqttid+= "mac:";

uint8_t mac[6];
char buff[10];
WiFi.macAddress(mac);

Expand All @@ -107,37 +109,35 @@ void LiveObjectsWiFi::connectNetwork()
m_sMac += (char)toupper(buff[j]);
m_sMqttid += (char)toupper(buff[j]);
}
if(i!=0) m_sMac += ':';
if(i!=0) m_sMac += ':';
}
m_sModel = m_sMqttid;
}

void LiveObjectsWiFi::checkNetwork()
{
if(WiFi.status()== WL_DISCONNECTED)
connectNetwork();
}

void LiveObjectsWiFi::disconnectNetwork()
{
outputDebug(INFO,"Disconnecting WiFi");
WiFi.disconnect();
}

void LiveObjectsWiFi::messageCallback(int msg)
{
LiveObjects::get().onMQTTmessage(msg);
}







void LiveObjectsWiFi::addNetworkInfo()
{
String tmp;
tmp = WiFi.RSSI();
tmp = String(WiFi.RSSI());
tmp += " dbm";
if(m_Protocol == MQTT && m_Encoding==TEXT) addToPayload(easyDataPayload[JSONVALUE].createNestedObject("networkInfo"),"mac",m_sMac,"ssid",SECRET_SSID,"ip",m_sIP,"strength",tmp);
else addToPayload(m_sMac,SECRET_SSID,m_sIP,tmp);
if(m_Protocol == MQTT && m_Encoding==TEXT)
addToPayload(easyDataPayload[JSONVALUE].createNestedObject("networkInfo"),"mac",m_sMac,"ssid",SECRET_SSID,"ip",m_sIP,"rssi",tmp);
else
addToPayload(m_sMac,SECRET_SSID,m_sIP,tmp);
}
#endif
38 changes: 38 additions & 0 deletions src/examples/1_send_data/1_send_data.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/******************************************************************************
INCLUDES
******************************************************************************/
#include "arduino_secrets.h"
#include <LiveObjects.h>
/******************************************************************************
USER VARIABLES
******************************************************************************/
uint32_t messageRate = 15000; // stores the current data message rate in Milliseconds
unsigned long uptime; // stores the device uptime (sent as fake sensor data)
unsigned long lastMessageTime = 0; // stores the time when last data message was sent

/******************************************************************************
USER PROGRAM
******************************************************************************/
void setup() {
delay(2000);
Serial.begin(9600);
Serial.print("\n*** Live Objects SDK for Arduino, revision ");
Serial.print(SW_REVISION);
Serial.println(" ***\n");
lo.setSecurity(TLS);
lo.begin(MQTT, TEXT, true);
lo.connect(); // connects to the network + Live Objects
}

void loop() {
if (millis() - lastMessageTime > messageRate) {
// collect data periodically
Serial.println("Sampling data");
uptime = millis();
lo.addToPayload("uptime", uptime); // adding 'uptime' value to the current payload
Serial.println("Sending data to Live Objects");
lo.sendData(); // send the data to Live Objects
lastMessageTime = millis();
}
lo.loop(); // don't forget to keep this in your main loop
}
23 changes: 23 additions & 0 deletions src/examples/1_send_data/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Send data to Live Objects

This example shows how to send some sample data (device uptime) to Live Objects using Arduino MKR NB 1500.
![diagram](img/send_data_diagram.png)

## Running
First of all, be sure that you installed the required libraries and generated an API key mentioned in the main README file, then:
1. Open "1_send_data.ino" sketch using Arduino IDE
2. Replace ```const char SECRET_LIVEOBJECTS_API_KEY[]="";``` in arduino_secrets.h with API key you generated
3. In ```lo.setSecurity()``` select security mode using ```TLS``` or ```NONE``` according to board abilities shown in **Compatibility** point in main **README.md**
4. Upload *1_send_data.ino* sketch to your Arduino MKR NB 1500 board


## Verify
**Is device online:**<br>
If all went fine under **devices** tab on Live Live Objects portal you should see online your device identified by its modem IMEI:

![device_online](img/device_online.png)

**Is device sending data:**<br>
Under data tab on Live Objects portal you should see messages sent by your device, along with values *{ "uptime": xxxxx }*

![data_portal](img/data_portal.png)
16 changes: 16 additions & 0 deletions src/examples/1_send_data/arduino_secrets.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Cellular connection cerdentials, used only for GSM boards
extern const String SECRET_PINNUMBER = ""; // unless PIN is deactivated, specify your SIM card PIN number
extern const String SECRET_APN = ""; // specify the APN name (if needed)
extern const String SECRET_APN_USER = ""; // specify the username for your APN (if needed)
extern const String SECRET_APN_PASS = ""; // specify the password for your APN (if needed)
extern const String SECRET_SERVER_MSISDN = ""; // specify the number of server(gate)

// WIFI connection credentials, used only for WiFi boards
extern const String SECRET_SSID = ""; // unless PIN is deactivated, specify your SIM card PIN number
extern const String SECRET_WIFI_PASS = ""; // specify the APN name (if needed)

// Live Objects credential: paste below your API key (see Configuration > API keys on the portal).
// You API key must have at least the predefined 'MQTT Device' rights profile
// (alternatively: 'Device Access' read + write rights if need to customise the rights).
// Please note that you *must* use a TLS connection (MQTTS) if you grant more rights to the API key.
extern const String SECRET_LIVEOBJECTS_API_KEY = "";
Binary file added src/examples/1_send_data/img/data_portal.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/examples/1_send_data/img/device_online.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit ac0c1c7

Please sign in to comment.