====== LPWAN IoT Use Case: LoRa to AWS ====== Now, let's try to set up a real life //LPWAN// IoT topology. Consider the following scenario: {{:iot:lora.png?700|}} One embedded device (i.e. raspberry pi) running a Netualizer agent receives temperature and pressure readouts from a //[[https://www.bosch-sensortec.com/products/environmental-sensors/pressure-sensors/bmp280/|BMP280]]// temperature sensor. The //BMP280// and the raspberry pi are connected by means of a //SPI// I/O interface. Readouts are encapsulated on top of //CoAP// and transmitted over //LoRa// a few kilometers away to another rapsberry pi. This second raspberry pi, that acts as a //gateway//, decapsulates the //BMP280// readouts and encapsulates them into //MQTT// for transmission over Ethernet to AWS. A single controller configures and deploys both devices in the field. The real devices look like this: {{:iot:1.jpg?800|}} Let's create a new project by clicking on //File ⇒ New ⇒ Project// and name it //loraAws//. Make sure that the local built-in agent does not get attached (uncheck box): {{:iot:2.png?1000|}} Now, let's attach the agent running on the device sensor by clicking on //Agents ⇒ Add Agent//: {{:iot:3.png?1000|}} Then enter the management IP address of the raspberry pi that runs the Netualizer agent: {{:iot:4.png?1000|}} Double click on the agent entry: {{:iot:5.png?1000|}} And let's name it //sensor//: {{:iot:6.png?1000|}} Now, attach this Netualizer agent to the project by entering //Yes//: {{:iot:7.png?1000|}} Then add the physical layer and select the //LoRa radio//: {{:iot:8.png?1000|}} And place the physical layer on the configuration: {{:iot:9.png?1000|}} Let's add a LoRa layer and name it //lora//: {{:iot:10.png?1000|}} And place it on top of the physical layer. In order to support IPv6 over LoRa, we need an adaptation layer as LoRa cannot handle the minimum 1280-byte MTU size of IPv6 datagrams. We can use the //Bluetooth Low Energy// (BLE) IPv6 adaptation mechanism for this. Therefore, create a new //6LoBTLE// layer and name it //adaptation//: {{:iot:11.png?1000|}} Similarly, place the //adaptation// layer on top of the //lora// layer. Next, add IP and UDP layers and respectively name them //ip// and //udp//. Keep the defaults: {{:iot:12.png?1000|}} Then create a CoAP layer, name it //coap//: {{:iot:13.png?1000|}} And place it on top of the //udp// layer: {{:iot:14.png?1000|}} Let's add the SPI interface and call it //spi//: {{:iot:15.png?1000|}} Put it on top of the //coap// layer: {{:iot:16.png?1000|}} To avoid configuring every single layer to support the sensor, let's create a BMP280 helper layer instead and call it //bmp280//: {{:iot:17.png?1000|}} Then place it on top of the //bmp280// layer. This finalizes the stack on the sensor device: {{:iot:18.png?1000|}} We will get back to this stack later to configure a few more things. For now, let's configure the gateway, add a new agent by clicking on //Agents ⇒ Add Agent// and enter the management IP address of the Netualizer agent running on the gateway device: {{:iot:19.png?1000|}} Then double click on the agent entry: {{:iot:20.png?1000|}} And name the configuration //gateway//: {{:iot:21.png?1000|}} Add it to the project: {{:iot:22.png?1000|}} Let's build the LoRa stack first. Create a physical interface and select the //LoRa radio//: {{:iot:23.png?1000|}} Place it on the configuration: {{:iot:24.png?1000|}} Add a LoRa layer and name it //lora//: {{:iot:25.png?1000|}} And place it on top of the physical layer. As before, create a new //6LoBTLE// adaptation layer and name it //lowbtle//: {{:iot:26.png?1000|}} Let's build the whole stack up to the CoAP layer as we did for the sensor device, keeping all default parameters: {{:iot:27.png?1000|}} Now we need a stack for the other side of gateway. This is the stack that connects to AWS. First create another physical layer and select the //wlan0// interface to connect the public Internet: {{:iot:28.png?1000|}} Then add an ethernet layer that name it //eth//: {{:iot:29.png?1000|}} Place this layer on top of the physical layer and create an IP layer that we name //ip2// since //ip// is already in use: {{:iot:30.png?1000|}} The //ip2// layer is placed on top of the physical layer and a TCP layer is created and named //tcp//: {{:iot:31.png?1000|}} //tcp// is put on top of the IP layer. To interact with AWS, we need security so we add a TLS layer that is named //tls//: {{:iot:32.png?1000|}} The TLS layer is placed on top of the TCP layer. Now let's create an MQTT layer to talk to AWS IoT, it can be named //mqtt//: {{:iot:33.png?1000|}} This layer is placed on top of the TLS layer: {{:iot:34.png?1000|}} Next thing we need is access to AWS. Rather than configuring every stack to support it we can create an AWS layer and name it //aws//: {{:iot:35.png?1000|}} Place the //aws// layer on top of the //mqtt// layer. This finalizes the stack. Now, we can configure a few more things. Let's forward every packet that arrives a the //coap// layer must be forwarded to the //aws// layer. We can right click on the //coap// layer and click on //Destination Peer// {{:iot:36.png?1000|}} Let's select the //aws// layer as destination: {{:iot:37.png?1000|}} After this the configuration shows the packet path between one stack and the other: {{:iot:38.png?1000|}} Now, let's configure the //aws// layer. Let's right click on the layer and select //Action//: {{:iot:39.png?1000|}} Then click on //publish// to push the readouts that arrive to the AWS layer into //AWS IoT//: {{:iot:40.png?1000|}} Then change the //Client ID// to match the AWS console information: {{:iot:41.png?1000|}} Copy/paste the information: {{:iot:42.png?1000|}} Similarly, select the //EndPoint// to match the AWS console information: {{:iot:43.png?1000|}} Copy/paste the information: {{:iot:44.png?1000|}} Then select the //Topic// field: {{:iot:45.png?1000|}} And enter //Temperature//: {{:iot:46.png?1000|}} Click on the //CA certificate//: {{:iot:47.png?1000|}} And select the file: {{:iot:48.png?1000|}} Also click on the //Client certificate//: {{:iot:49.png?1000|}} And select the corresponding file: {{:iot:50.png?1000|}} Finally select //Client private key// (and select the corresponding file): {{:iot:51.png?1000|}} Now, let's figure out what the LoRa address is by right clicking on that layer. It should say (if defaults are used) //11//: {{:iot:52.png?1000|}} As promised, let's go back to the device sensor by double clicking on the agent entry: {{:iot:53.png?1000|}} Right click on the LoRa layer and select //Dest Address// to change the destination address: {{:iot:54.png?1000|}} Enter //11// as destination address: {{:iot:55.png?1000|}} On the CoAP layer, enable //Post Readouts// to push readouts to the gateway device: {{:iot:56.png?1000|}} On the gateway device, right click on the IP layer of the LoRa stack to figure out what the destination IPv6 address is: {{:iot:57.png?1000|}} Back on the sensor device, change the //Url// field to specify the CoAP server on the gateway device: {{:iot:58.png?1000|}} Enter the URL as //[IP Address]/Temperature//: {{:iot:59.png?1000|}} Then on the gateway device select the CoAP layer select the //Forward List//: {{:iot:60.png?1000|}} And enter //Temperature//: {{:iot:61.png?1000|}} Then we can start the suite by clicking on //Scripts ⇒ Run Suite// {{:iot:65.png?1000|}} We can look at the device on the AWS Console: {{:iot:62.png?1000|}} And launch a client to subscribe to //Temperature// readouts: {{:iot:63.png?1000|}} After a few seconds we can see the temperature readouts showing up: {{:iot:64.png?1000|}} That's it. We have a temperature sensor pushing readouts using CoAP over LoRa and arriving to a gateway that pushes them to AWS.