As part of my project in the Arduino Touch Less, Do More challenge, I wanted to get Arduino Cloud data and use it in an App created in MIT App Inventor. I also wanted to change parameter values using the app. This is a basic tutorial on how to make the API requests to communicate with Arduino Cloud so it can be adapted to other projects. The documentation for using the API is here but I will try to show how to use the App Inventor blocks to get the desired response without delving too far into these (or such that layman like myself can use them).Part 1: Setting up the Variables and Obtaining IDs
Once you have a thing setup (a 'thing' is Arduino Cloud nomenclature for a project with an associated WiFi board). Each 'thing' has an id which can be seen at the bottom of the thing overview. This id should be noted down as we'll need it later:
Here we have setup two variables. 'customerLimit' is an integer which can be written to and read while 'customerCount' can only be read on the Arduino Cloud Server.
On the things overview page you also need to obtain your secret ID value which allows you to communicate with the device. When you first generate this, you get given a document with with 'Client ID' and 'Client Secret' on. Download and keep this document safe as we'll need these values later!
So before moving on we should have three values:
- Thing ID
- Client ID
- Client Secret
After setting up an MIT App Creator account, and after clicking create a new project, we are starting with a clean screen:
Under the layout tab in the left sidebar, we add the 'tableArrangement' to the top of the screen. We also edit the properties on the right so width fills the parent object:
Under the user interface tab, we add three labels and one spinner into the four boxes of the table previously added:
We edit the two labels on the left to indicate the names of the properties using the properties tab. The property with the read and write abilities is placed next to the spinner. We also rename the components using the components tab on the right. For the customer count value, we will put a placeholder of 0 (we will soon obtain the actual value from the cloud). For the spinner we add values they can select by comma separating them:
You may check out the progress at any time using the connect the button at the top.
We then add a connect button, a refresh data button and a final label to help us see what messages are being sent and received:
Finally, we add Web capabilities under the connectivity tab.
This is all we need to make a basic functioning app. We can now move on to programming the app behaviour and communicating with the Arduino Cloud.Part 3: Communicating with the Arduino Cloud
This is where the project gets a little bit more tricky as communication depends quite a bit on message format so be careful with unnecessary colons and quotation marks in the next bit.
At the top right of the App Inventor screen we need to switch to the Blocks view. Again, we will start with a blank screen:
Arduino Cloud API uses something called OAuth 2 which this website describes as
"an authorization framework that enables applications to obtain limited access to user accounts on an HTTP service."
This essentially means that if we want our data, the cloud needs to authorise ourselves every time we try to access it (a type of logging on if you will). Our first step will be to ask for authorisation using our Client ID and Client Secret values we obtained in part 1. If cleared, we will be given an key (called the 'access token') which we can use to access our data for a limited amount of time.
We are going to program the app so when we click the connect button, we get this key to our data. Let's first initialise the variables:
The first three variables are the values we obtained in Part 1. The next two variables are IDs for the properties which we are trying to get their values. We will soon obtain the IDs and the values. The next pair of variables will hold the values of the variables. gotAccessToken will be true when we have the key to our data. strAccessToken will hold the key once it is sent to us. strResponse is a container to hold any response we get from the requests we send. On the right we have four variables. These are used in requesting for the key (access_token) as shown by this section in the documentation:
Now the variables have been initialised, we will request the access token at the push of a button. This is done with a POST request with the format seen above:
The server will then respond with a message so we need a code block to format the received message. This block will be used to format all our received messages so we will adapt it as we go on.
Let me take you through what is happening here. When we receive a response from our request, it will be in a JSON format. This is a format which the data is arranged in a list of key-value pairs. We define a variable to be this decoded list. A response code of 200 means our request was approved. We will be looking for a response code of 200 when we request the data later too. We only want to get a access token once when we connect so our last if statement ensures this. We then look at our list of key-value pairs and ask for the value of the access token which is stored in the strAccessToken variable. If we get this far, it means all is well. If not, check your client secret ID variables for any spaces (I first failed because of an wandering space!) or if its been copied incorrectly. We then hide the connect button as we don't need it anymore. The empty else statement will be used in a minute but for now, it can be left empty. I recommend testing it again at this point. You should see 'Successful connection' followed by an extremely long access token.
Our next move will be to receive the values of our two Arduino Cloud properties (customerCount and customerLimit) when we press the Refresh Data button. These properties also have IDs which will be needed if we're going to change anything about them. As we want to change the value of customerLimit, we'll need to obtain its property ID.
The following code of blocks will represent this section of the documentation:
In the code blocks, this is:
The variable 'requestSource' initialised on the right will help with the if-else statements when dealing with the reply we receive from the server. The authorisation token is added to the header of our request. Important:There is a space after Bearer so the string is "Bearer ". To deal with this reply we need to edit the code block we made earlier. In the picture below we have added an if-else statement in the empty else statement we had earlier:
In the code block which we sent the property request we also defined the variable 'requestSource' to equal "refreshData" so when we receive a response, the code within this new if-else statement will handle the response.
In response we will receive a list of the Arduino Cloud properties. We defined two properties so we receive a list of length 2 long. At Index 1, is another list of key-value pairs holding everything about that Arduino Cloud property. We desire the 'last_value' and also the 'id' for each variable. We store these values in their respective variables before setting the text in the app.
Now when we test it out on the phone, the values should update:
Now we have received data, our final task is to use the app to update the data on the server. This is done with this section of the documentation:
This time we are going to use a PUT request when we change the scroller value:
Here we have two headers and the URL has changed. We will also receive a response after posting so we need to add one final section to our receive text code block just to tell us everything is okay:
Now when we select the value (say 9 here), the server will be updated. This can be seen if we click refresh data or we check on the Arduino Cloud dashboard.Afterword
I hope this project gives a baseline to start any of your projects. This was my first project using API so I am also very new to this topic. I am thankful for this other API project which connected to the google cloud API, and also the people who responded to my forum questions here. I will be publishing my project for the Arduino 'Detect and Protect' competition soon in which I use this tutorial. I am thankful also for Arduino for sending me an Arduino MKR WiFi 1010 to use in my project as it has already taught me to use an API!Some Adaption Ideas
- If you change the update code into a function, a automatic update switch can be programmed.