The Web App iOT Client (part three of three)

And we finally arrived at the last part of our Blockchain iOT (proof of concept) POC where we will explain how to read data from a web page that the API server (which we described in the second post) stores on the blockchain. In this case we have the following scenario: the device (see the first part) is transmitting data relating to temperature, humidity and GPS position to a rest server API which in turn registers them within the blockchain, creating a smart contract called IotData for each data received. In the blockchain there is another smart contract, called IotDataManager that collects all these instances and makes them available by exposing some methods.

Web App Architecture

The web app it's very simple. It is a website written in C # with Asp.net Core technology and practically made up of a single controller with two actions: the first one refers to the page concerning the reading of the temperatures on the blockchain, the second one concerns the detection of the device path by detecting the GPS points stored during the recording of values. In both cases no server technology will be used, but the Web3.js library will be used, a javascript library that simplifies RPC communications with the Ethereum endpoint through an ad hoc provider

Let's start

First of all we have to install the Web3.js library. You can do it with the command line using npm (install it if you don't have in your pc)

 

npm install -g web3

We used an interesting chart.js plugin that is able to process data in real time by taking them from a stream. The plugin can be downloaded from the site and is very easy to use. At this point, all that remains is to dive in the code and analyze its main parts. Insert the link to the js libraries used in the code:

<script src="~/lib/moment/moment.min.js"></script>
    <script src="~/lib/charts/chart.js@2.8.0.js"></script>
    <script src="~/lib/charts/chartjs-plugin-streaming@1.8.0.js"></script>

When we want use the web3 library we have to choose a provider. We now are using Ganache that simulate a real Ethereum Blockchain and so we'll connect through a http provider. Use the following line of code to instantiate your provider

web3 = new Web3(new Web3.providers.HttpProvider("http://localhost:7545"));

You should always check the version of the library to avoid any syntactical errors. To check which is the current library's verse use the following line of code (possibly run from your browser's command line)

var version = web3.version.api;

For each Smart Contract we want to use we need to get the Json chaimata 'abi' format interface. This will allow us to recall an instance of that particular Smart Contract from the blockchain. In addition, to request a particular instance we must also provide its Address assigned by Ethereum at the time of creation. We get this address when we perform the smart contract migration on Ganache via the 'truffle migrate' command

var abi = JSON.parse('[{"constant": true,"inputs": [{"name": "","type": "uint256"}],"name": "iotdata",...   
var address = "0x7e03d3fEd772AFA633B3Fe0889Be03bA4F5d591E";

Here the result of the migration of IotDataManager Smart Contract where you can get the address of deployment

We get the instance (the only one) of the IotDataManager smart contract

 var iotDataManagerContract = web3.eth.contract(abi);
 var iotDataManagerContractInstance = iotDataManagerContract.at(address);

Now we are ready to invoke any method, both those that read the status of our Blockchain and those that carry out transactions with relative use of Gas. First we see how much data has arrived and stored in Blockchain. Recall that every reading that comes from the device and is stored in the Blockchain causes the creation of an IotData type smartcontract which is in turn stored in the iotDataManager which simulates the functionality of a DataBase. Let's invoke the method 'getNumberOfIotData()' and we get this kind of response (as you can get from chrome debugger)

 

In the solidity code of the smart contract IotDataManager there is an array containing all the addresses of the IotData smart contracts and an associative array that returns a structure with the recorded data corresponding to an address

let's take the last recorded data with its temperature and update the dashboard

 var lastDataAddress = iotDataManagerContractInstance.getIotDataAddress(tot - 1);
 var lastResp = iotDataManagerContractInstance.getIotData(lastDataAddress);
 var lastTempValue = parseFloat(lastResp[1]);
 updateDashboard(lastResp);

 Here is the code of updateDashboard(lastResp)

Now let's analyze the last part of our javascript code

The onRefresh() function is part of the graph configuration that is displayed and indicates which data must be published in correspondence with the Cartesian axes of the graph itself. The current time is reported on the X axis and the result of the call to the getIotdata () function is reported on the Y axis. This function checks that new values have arrived. If they arrived then it takes the last arrived (remember that the device launches the data once per second) otherwise it keeps the last value. The final result is the graph shown below where at the Out of Range values ( > 25 dgree) there is a registration in the table on the right

With the same type of logic you go to query the blockchai to capture for example the last 10 positions indicating exactly where the device has actually covered the GPS points

The visible result on a Google Maps will be the path of the device reported by the Makers that are inserted on the map at each recording

Conclusions

In this series of posts we have covered the main aspects related to a Proof of Concept of type iOT Blockchain. We have deliberately omitted all those aspects of authentication and security necessary on these occasions which can then be subsequently implemented as an improvement to the POC

 

 

 

 

REST Server Interface between iOT device and Ethereum Blockchain - Part two of three

We continue in our example. After configuring our iOT device (see my previous post) so that it can transmit data to the REST Server, let's see how to configure the API service that will transmit the data to the blockchain after receiving them from the device. In the below picture you can see the architecture of this Proof Of Concept:

The server API is an ASP.Net Core server consisting essentially of a single controller API. The controller receives the data from the device through a POST call (see the python client deployed on the device Linklt), receiving a very simple Json that is mapped in a POCO class structure of this type:

The controller method that implements the POST does nothing more than prepare the message to transmit the transaction data to the Blockchain and wait for the response of the transaction on the blockchain itself. In the next section we'll see what kind of response the server is receiving. Here the server controller code

[HttpPost]
        [Route("api/temphum", Name = "TemperatureAndHumidityFromDdevice")]
        public async Task<IActionResult> TemperatureAndHumidityFromDdevice(IOTData iotData)
        {

            var web3 = new Web3(ethereumAddress);

            var gasForDeployContract = new HexBigInteger(6000000);
            var deploymentMessage = new IotDataDeployment()
            {
                FromAddress = BC.GetDefaultAccount(),
                Gas = gasForDeployContract,
                DeviceID = iotData.DeviceID,
                Temperature = iotData.Temperature,
                Humidity = iotData.Humidity,
                Lat = iotData.Lat,
                Lng = iotData.Lng,
                IotDataManagerContract = BC.GetIotDataManager_Address()
            };

            var deploymentHandler = web3.Eth.GetContractDeploymentHandler<IotDataDeployment>();
            var transactionReceipt = await deploymentHandler.SendRequestAndWaitForReceiptAsync(deploymentMessage);
            var newIotAddress = transactionReceipt.ContractAddress;


            String result = newIotAddress;
            return Ok(result);
        }

 

Solidity

How are smart contracts structured on the blockchain? The figure below describes one of the two smart contracts deployed on the blockchain called iotDataManager.

This smart contract works as a database of device data. Whenever the API Server makes a call it actually invokes the constructor of the smart contract called iotData whose code is reported entirely below

import "./IotDataManager.sol";
contract IotData {
     string public deviceid;
     string public temperature;
     string public humidity;
     string public lat;
     string public lng;   
     constructor (
         string memory _deviceid, string memory _temperature, string memory _humidity, string memory _lat, string memory _lng, address _IOTDATAMANAGER_CONTRACT) public {
             deviceid = _deviceid;
             temperature = _temperature;
             humidity = _humidity;
             lat = _lat;
             lng = _lng;
             IotDataManager manager = IotDataManager(_IOTDATAMANAGER_CONTRACT); 
             manager.storeIotDataReference(address(this), _deviceid, _temperature, _humidity, _lat, _lng);             
         }        
          function ()  external {
            // If anyone wants to send Ether to this contract, the transaction gets rejected
            revert("no eth accepted");
        }
}

The constructor receives the device data and the smart contract address iotDatamanager as input. Inside the constructor we already know the address that the Ethereum Virtual Machine has assigned us and this allows us to invoke the iotDataManager method that stores data in correspondence with the newly created smart contract address. As you can see from the figure above the smart contract iotDataManager will then offer the Dapp the possibility to invoke the other method to retrieve data at the respective address, but we will see this in the next post in which we will describe the web app that will use web3.js.

Caveat

An important thing to take into account is the fact that after creating the Server API and verifying that everything works using IIS Express, everything must be published on an IIS Server otherwise our device will not be able to communicate. IIS Express is in fact just a process that uses the Loopback interface which is fine for all the processes inside our machine, but which is not visible to any external client to our machine.

Results

Once our API Server is published we can run the Python program on the device and see how the blocks related to each call are concatenated on the Blockchain, while on the console of the device we see the addresses of the smart contracts iotData created for each call

Conclusion

see you to the next post where we will see how to build a web app that using web3.js technology will display real-time data coming from the device

Configuring Linklt Smart 7688 as a Rest Client (to use it as a Blockchain iOT client)

We took a Linklt Smart 7688 device and configured it to make it a Restful client via a simple application written in Python. Of course then we will use this device later as an iOT device that transmits data on an Ethereum blockchain.

Linklt Smart 7688

The chosen device equips a Linux distribution defined as OpenWrt and is ideal for doing enough interesting tests for iOT applications. The system already starts with many useful features for the development of dedicated applications. There are already many modules that can be used by those who develop complex appications, besides the possibility of plugging sensors of all kinds. We already find on the card for example packages such as python, node.js, git, curl and so on, and you can easily install any other packages that may be needed

Let's start to using it

First the device must be powered so take your mini-usb charger and connect it to the port with (very small) PWR written. Immediately the device turns on and the boot starts. You can see that the WiFi LEDs are turned on and as soon as it turns green it means that the device is able to provide a WiFi network to which you can connect via our PC (the device is in AP mode). Look for it among the available networks. The default name is Linlt_Smart_7688_xxxxx as you can see looking at the picture below

At this point, connect to the device's network and get an IP address with which you can communicate later. The subnet used by the LinkLt is 192.168.100.x

Open a browser (NOT Edge because the execution of the script for administrative management crashes, we have used chrome) and connect to the address 192.168.100.1 which will open the login page to access the administration site. The first time you connect, it will ask you to set a password that will be persisted on the device until a possible hard-reset

Once inside we move on to the network tab where it will be possible to switch from the AP mode to the Station Mode in which it is possible to connect the device to the local WiFi network we want, by entering the appropriate network password. At this point also the device can access to internet and we too can switch to the local WiFi and share the same network of our device. After restarting, LinkLt is ready.

 

To detect the IP received by our device use a Network Scanner to discover all assigned IP Address. We've used IPScan a free tool that you can download from internet. Our result are shown below:

Connect to Linklt

To connect to the device we will use an SSH connection using the classic SSH client called PuTTY downloadable from the network as open source software.

Once the PuTTY console is open, we insert the IP address of our device and get a root console (make login with credential 'root' and the password you've choosen before) from which we can start to make the device operational. From the command prompt, download the python responses module using the language package manager called 'pip' and give the command as shown in the figure

Write the Client

At this point, all we have to do is start writing some code. We should not expect to have Visual Studio installed and for this we will have to be content with a historical editor for those who have been using Linux for a long time called Vi, obviously already present in the device as part of the openWRT system. Type vi restcli.py from the command line and open our editor. We enter editing mode (one of the two modes of vi: 'editing' and 'command') and insert the following lines of code:

Enter 'Esc' and 'colon' and wq to save and quit from the editor. Here the complete code:

import requests
import time
import random
import json

count = 0

lats = ["44.534041", "44.535264", "44.536947", "44.539325","44.540732","44.542139","44.543852","44.545542","44.546689","44.548188"]
lngs = ["11.124427", "11.121359", "11.117056","11.110705","11.107121","11.103366","11.098850","11.094579","11.091575","11.087616"]
while (count < 10):
    rnd = random.uniform(11, 30)
    truncatedrnd = round(rnd, 2)
    iotData = {'DeviceID':'Link Smart 7688', 'Temperature': str(truncatedrnd), 'Humidity': '89.2', 'Lat':lats[count], 'Lng':lngs[couunt]}

    h = {'Content-Type': 'application/json'}
    rp = requests.post(""http://localhost/iotapi/api/temphum", data=json.dumps(iotData), headers=h)
    print(rp.text)
    time.sleep(1)
    count = count + 1   
print ('end loop')


The code is very simple. We define two arrays of strings containing the latitude and longitude of ten GPS positions. We begin a cycle (only of ten iterations) in which a random float is chosen between the values 11 and 30, the decimal digits are truncated after the second and the payload of the call Rest is constructed. After declaring a header containing the Content-Type the http request is executed indicating the URL, the Payload and the header just built. We wait synchronously for the answer which will then be printed on the screen. At each iteration, you wait for a second. If you use the https protocol add the verify = False parameter to the call so as to avoid verification problems of a non-secure certificate (such as for example a self-signed certificate).

Launch the client by the command prompt line python restcli.py. The server listening for this call is an API server that inserts this data into a Blockchain creating a smart contract instance for each call. The result of the call is the address of the newly created smart contract

 Our client rest has been programmed to simulate sending the temperature and GPS position and can be used in many areas where a cold chain must be certified with absolute certainty (transport of medicines, transport of frozen food, ... ). The use of this device, however, can be absolutely extended to domotics (we think of the detection of images in a security system) or to new applications for the automotive sector (let us think, for example, of the registration of the paths of a car in the insurance sector). You will simply need to insert the detector to obtain the necessary physical data.

Conclusion

In the following posts we will see the part related to the Server API that receives the data from our device and inserts it in the bloackchain, while in the final post we will see a web application that reads the data in real time from the blockchain as soon as inserted by the API server part.