Build a DIY Mars Probe using AWS Greengrass IoT v2 with a Raspberry Pi | ACG Projects

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
(upbeat music) - Well, hello there, Cloud Gurus and welcome to another ACG project. In this project, we're gonna explore AWS Greengrass and IoT devices. Specifically, we're gonna turn this pile of parts into an off-grid remote controlled image and data collection device. We'll be using a Raspberry Pi Zero, a Pi Camera, a cellular modem, and some other bits and pieces along with AWS Greengrass version two. Yes, you heard correctly there is now a Greengrass version two which was released at the end of 2020. AWS still supports Greengrass version one, which they now lovingly refer to as the classic edition, but they are encouraging new development to use the version two path. And that's the path we're gonna take. No worries if you don't have a Raspberry Pi, you can still follow along and learn. Turns out that a t4g.nano EC2 instance does a reasonably good job at standing in for a Raspberry Pi 3 or 4. So I'll first take you along the path of getting a nano size EC2 instance set up as a Greengrass version 2 core device. And we'll get it to send and receive some messages. In the second half of the project, we're gonna be working with this little guy, a Raspberry Pi Zero W, and assembling a solar powered off-grid data collection station. So if you're like me and you have a few of these little devices lying around, let's go put them to work. Here's the set up for our project. We've got some good news and I've got some bad news. The good news is that our scrappy space startup has just won a very lucrative contract to deploy thousands of data collection sensors on the surface of Mars. The bad news is that virtually all of our plan budget will be needed to actually launch and land the devices on the red planet. We've been tasked with building out a device management and data collection system on the cheap. Upon requests, the device will need to snap a picture and collect environmental readings. Since data connections on Mars aren't very stable, the solution will need to accommodate intermittent connectivity plus there are no power plugs on Mars, so it will have to be self-powered. Now, before all you space buffs start picking apart this premise, I'm gonna ask you to suspend disbelief for a little while. Yes, I'm sure that space radiation would ravage our off-the-shelf components. And while I'll be using a cellular modem for connectivity, I'm quite sure that there's not a 5G data network on Mars just yet. Heck, we're not really even a scrappy space startup, are we? But remember when we were kids and we played make believe, anything could happen in our imagination. Let's go back to that place for a little while. For our architecture, we're gonna use AWS Greengrass version two as our control plane. We'll outfit our Raspberry Pi or FakePi EC2 instance with the needed components to turn them into what Greengrass calls core devices. Core devices can act as data collection points themselves and they can also act as local proxies for other devices. Sort of like a collection point or a gateway back to Greengrass. To communicate with our core devices, we're gonna use MQTT. MQTT is a lightweight messaging protocol used widely in IoT applications. If you're familiar with other message queuing design patterns, you'll be right at home with MQTT. It's cues are called topics and devices can subscribe and publish to topics to send and receive messages. This is how we will send instructions to our devices and get responses back. We're also going to have our device upload the captured image to an S3 bucket. For our physical device, I'm gonna be using a Raspberry Pi Zero powered by a lithium ion battery pack and a solar panel. We'll connect it to the internet with a cellular modem or as it's called in the Pi world a cellular hat. Then I'll cram all that stuff into a waterproof box to see just how long the thing can stay online in the elements. Let's get started. As I said in the intro I'm gonna do this demo two ways. The first way will be with an EC2 instance for those that don't happen to have a Raspberry Pi. The second way will be with a Raspberry Pi Zero. For the EC2 version, we'll be using a t4g.nano Arm64 instance with a Debian 10 AMI, which is a reasonable stand in for a Raspberry Pi 3 or four. For the Raspberry Pi Zero, it uses an Arm 6 architecture with a very small memory footprint. So it's gonna require a little special treatment. To get started with our FakePi version, let's spin up a t4g.nano instance and SSH into it. Note that I'm using a Debian 10 AMI and the default login user is admin. (soft upbeat music) The first thing I always do with any new instance is to make sure it's up to date. Once that comes back, we'll need to install some components. Unzip python3.pip cmake and a relatively recent Java virtual machine. AWS will recommend that you use their Corretto JVM, but I've had good success with OpenJDK and some other more specialized JDKs as we'll see in the Pi Zero version. While that's installing, let's go do some other work. First, we're gonna create an S3 bucket. This bucket will be used for hosting our Greengrass custom component artifacts as well as our data that our probe captures. (soft upbeat music) Now let's go do some IAM work. We'll first create some policies and roles. And since we're gonna be using auto-provisioning with Greengrass, we need to create a role which will allow our devices enough access to provision themselves. (soft upbeat music) I'll call this policy custom Greengrass provision policy. Since we're here in policies, let's create another policy we'll need. This policy will allow our Greengrass devices to access S3, which they'll need to both download our code components and also upload our captured device data. We'll call this policy custom Greengrass S3 access. Now, I'm gonna create a user account that we can use for device bootstrapping. I'll call it Greengrass bootstrap, and we're only gonna need this for it's access keys and secret. Save these somewhere as you're gonna need them later. We also need to assign the custom Greengrass provision policy to this user account. (soft upbeat music) From the IoT console, go to Greengrass, then core devices. We're gonna set up our FakePi as a core device. We'll click on setup one core device. And for the device name, let's just call it FakePi. For group, we'll call our group MarsProbes. Now the group is important in that we can deploy components to the group and everything in that group gets the same deployment. Pretty handy if you're dealing with thousands of devices. The console will generate two command lines for you. One to download and unzip the Greengrass core components and the other to install and provision the device. First, we need to set the access key and secret from our Greengrass bootstrap account as environment variables on our instance. Now, AWS will tell you a better way is to use STS to generate temporary credentials and assume the provisioning role that we set up. In the end you'll ultimately get an access key and a secret that you can export as environment variables just the same. These won't be saved by Greengrass in any way, and we'll go away on the next log-out or reboot, so this is a pretty low-risk activity. And before anyone freaks out that I showed access keys and secrets in this video, do know that they are long gone as soon as this video was captured. Copy and paste both lines and execute. After Greengrass installs, you should see it show up in the console under the Greengrass core devices after a few minutes. (soft upbeat music) You now officially have a Greengrass IoT core device connected to AWS. Now, because our devices are pretty light on RAM, we're gonna need to tweak the default Greengrass settings to let them run a little smoother. You can skip this step, but you might run into lots of swapping when the meager memory is used up by the JVM. And that slows things way down. To make this adjustment, we need to revise our deployment such that it sends a specific JVM configuration to the device. The component that we'll be setting is called AWS Greengrass nucleus. We first have to select our deployment that contains our device. Off the list of public components, I'm gonna select AWS Greengrass nucleus and next. Now here's a key part. Select the radio button next to the component and click configure component. You'll see on the left-hand side of the screen the default configuration. And we need to add some extra JVM options, so we're gonna paste that on the right side of the screen. This bit of configuration is the recommended configuration for a reduced memory footprint. AWS docs do also have an absolute minimum version of this command, but I ran into errors when they tried using that version. This reduced configs seems to work nicely. We confirm our changes and just keep hitting next then deploy. We can watch the deployment happen over on our device by watching the Greengrass log or watching the processes using something like top. After things appear to quiet down on the log activity and our deployment status changes to completed on the deployment console page, we know that we've deployed the new memory settings. Now, sometimes I have seen the deployment get stuck at active when by all indication the deployment actually completed. I didn't pay too much attention to this. But in this case for good measure, I prefer to reboot my device after that memory change. I've seen cases where the change didn't take effect even after restarting the Greengrass service. Rebooting seemed to do the trick. Next we're ready to build our component. For this EC2 example, I created a simple Python program that uses the AWS IoT SDK to listen to a topic and respond when something appears on that topic. We need to create two parts. The first is the actual Python program, and the second is a recipe in JSON or a YAML. The recipe describes all the dependencies, access, and artifacts that our component needs. I put lots of comments in the code, so I'm not gonna step through that here. Now, there are a few important parts to this recipe. You can do it in JSON or YAML. I just prefer JSON. The version is important here as that will signify the unique versions of this component. If you start playing around with this example, you'll probably have several versions as you debug. This bit here lets us publish and subscribe to the IoT Core MQTT topics. In production, you'd probably crank these down to just specific topics, but I left it wildcard here. This dependencies part is really important as it lets our component be able to get access tokens, to access other AWS services. In our case that will be S3. In fact, let's go handle that little bit of IAM right now. When you provisioned your first core device, the process created a few IAM policies and roles. If you left everything default, you should find a role called GreengrassV2TokenExchangeRoleAlias. This is the role that our core devices will use. They don't use it directly, but rather that token exchange service handles the magic behind the scenes. Because we want our devices to be able to get input from S3, we'll add that policy we created earlier, the custom Greengrass S3 access. (soft upbeat music) Let's also copy our Python artifacts out to S3. Getting back to our recipe, the last part of this file will tell Greengrass what to install and how to run our Python code. In our case, we need to use pip to install some dependencies before we run the command. And our run parameter contains our show commands to get our program kicked off. Notice the -user parameter on pip and the -u on the Python shell command. Our Greengrass processes will run as a special Greengrass user account created during provisioning ggc_user. We want to be sure that the dependencies and the Python is being run within the scope of that user. With our Python code out on S3, we are ready to create our component. From the Greengrass console, select components and create component. Here's where we paste in our JSON or YAML file that we just created. This JSON file should contain everything that AWS needs to get your component ready to deploy. (soft upbeat music) We can then click deploy and we're asked if we want to add this to an existing deployment or create a new one. Let's just add it to our existing one. Proceeding through the screens, we'll then see our new component under my components. And we'll also see our existing customized nucleus component under public components. We want to leave that one checked otherwise Greengrass will think we wanna remove nucleus from the core device which would be bad. Next, next, next, then deploy. (soft upbeat music) Same scenarios last time. You can watch the deployment from the Greengrass log and you can also watch the component being deployed by watching the simple Pub/Sub log file. If you go into your deployments, you'll notice that it also has versions. You can revise deployments to set new parameters or customizations or you can add and remove components. If you wanted to remove the simple Pub/Sub components, I could just revise my deployment and uncheck that component, it would then be removed. Now, what happens if your device is offline? Well, that's a strength of Greengrass. It's designed to work with devices that have intermittent connections. The next time your device gets connected to AWS, it will receive its set of instructions and do whatever it needs to do. You can test this by stopping your EC2 instance, setting up a deployment then starting it back up at some time in the future. Same thing goes for MQTT messages as we'll see later with our Pi Zero path. In fact, let's go send some MQTT messages. We can do that from the test console page. First, let's subscribe to some topics. How about all topics so we can see everything. We'll just enter hash or pound or whatever you call this thing in the topic filter. Now we can send a message to the topic that our Python code is listening on. We choose marsprobes/request and enter some message. (soft upbeat music) We should get a response back with a URL to a file the component placed out on S3. So this is good news. We're able to send and receive data from our IoT core device. Moving on to the Pi zero, ultimately I'm gonna assemble this Pi Zero with some additional components such as a power controller and a battery and a solar panel and an LTE cellular modem. That detailed installation is going to be on the GitHub repo for this project. For now, let's just get it working over wireless. Now I'm not gonna cover setting up a Pi Zero as there are plenty of tutorials out there on that. Just remember to use the light version of the Raspberry Pi OS. And remember to set up the wpa_supplicant.conf file for Wi-Fi and drop an SSH file into the boot partition if you're running the zero headless. Meaning without a monitor and keyboard. To get the Pi Zero running Greengrass, the setup is pretty much the same except for a few differences. First, I'm gonna do my updates. (soft upbeat music) We need to install some dependencies except the OpenJDK as we did on our FakePi. Those include unzip if it's not already installed, pip and CMake. (soft upbeat music) Next, we go into raspi-config. I'm gonna enable the Pi Cam interface. And because I'm using a cellular modem, I'm gonna go ahead and enable this serial port. I'll also expand the file systems since I'm already in here. Next, I'm gonna save some power by turning off audio and turning off the HDMI interface. (soft upbeat music) Now here's a key difference between using a Pi Zero versus a Pi 3 or a Pi 4. Pi Zero uses an Arm 6 architecture, and the OpenJDK 11 in the Raspberry Pi OS repo will not work with the Arm6 architecture. So we have to go looking elsewhere. I found a special Zulu Arm 6 JDK 11 from Azul. Here are the commands to install that. (soft upbeat music) And then we can proceed with the provisioning of our core device via the console and the copy paste commands. (soft upbeat music) If we place this device in an existing group, it will automatically pull down the components from our deployment including the JVM settings. If you don't place the device into a group at first, you can do that later and then the device will automatically download the latest deployment and component versions for that group. Now, for our Pi Zero, I've created a custom component that will listen on an MQTT topic, snap a picture and upload to S3, and then respond on a different MQTT topic with a URL to that picture. In my testing though, I've noticed that trying to deploy the new JVM settings and the snap picture component all at the same time just puts too much stress on the Pi Zero. So I'm gonna leave it out of a group and create a deployment that steadily rolls things out. I'm gonna send down the JVM config update by itself and then send down the custom Python program later. (soft upbeat music) Do be sure that you give Greengrass plenty of time to finish its deployment especially on the relatively slow Pi Zero. You can keep tabs on it by watching the logs or watching the processes in top. While we're waiting for Greengrass to do all that stuff, let's add the GGC user account to the video group so that it can access the camera device. I also want to add this user to the GPIO group as I'll have a temperature and humidity sensor which uses the GPIO pins. Once everything is settled, we can now reboot the Pi just to make sure that the JVM parameters have been properly applied. While that's happening, let's go back to our console and create our snap picture component. Same method as we used for our first component. One thing that I discovered is that apparently your artifacts must be contained within a bucket in the same region as the Greengrass instance you're using. Those eagle-eyed viewers might've noticed that I'm doing this demo in us-west-2 whereas I did the FakePi demo in another region. To get the component to work, I had to create a new bucket and copy the artifacts out to that bucket. Also, I had to add the new bucket to the custom S3 access policy so the Greengrass process can reach the bucket for downloading the artifacts. (soft upbeat music) You'll see that in this recipe we're adding the Pi Cam Python library and an Adafruit library for a DHT sensor. When this component is deployed, the device for the first time the pip command will pull down and install all the components. Now downloading and installing all those components for the first time takes a while. And I have noticed sometimes the Greengrass deployment process times out waiting for all the components to install. I'm sure we could adjust the timeout somehow, but we're gonna help things along by pre-installing those components. But we must install those under the Greengrass runtime user account. So now with the first deployment of our component, pip will notice that we've already satisfied the dependencies and shuffle right on along. Now, just a word of caution here. If you still have your FakePi instance running and you deploy it to that instance, the deployment will fail on that system because Pi camera won't install on a non-Raspberry Pi device. So the pip command will air out and thus make Greengrass report that the installation failed. You can ignore this or remove that device from the group if you'd like. Once deployed, we can again go out to our MQTT test bench and send a message. If we're living right, we'll get back at JSON response with a URL to an image that was captured. Do keep in mind that the little Pi Zero isn't very powerful. And in my case, it was taking up to a good 10 seconds or so before I got a response back, especially over cellular. Of course this delay would be greater if we had the Pi configured to only connect to the internet say every 10 minutes for example. But that's the benefit of the MQTT messaging queue approach. It's designed for those types of intermittent connections. In the MQTT test console, I can set attributes for the message and I can keep that message in the queue until the device comes back online. We can demonstrate this by shutting down the Greengrass process on the Pi. Then creating our message with the retain message flag selected. (soft upbeat music) Then when we start back up the Greengrass process, it will see the new message and act upon it. As Greengrass comes back up, it sends some status information on the MQTT queue that you'll see here. And once our snap picture process is up and running, we should see a response come through. And here it is. Additionally, the core devices can also act as a local proxy for MQTT messages for other local devices. And this is really useful for those sensors that don't have the capability or capacity to store or queue data locally. Now you can have some more fun with MQTT and Greengrass by using a tool like Node-RED to build some simulations if you like. But the rest of this video will focus on building out the hardware components of our MarsProbe. This physical build consists of a few basic components. We'll start with the brains, the Raspberry Pi Zero W. I've customized this Pi slightly by soldering on the GPIO pin outs. I'm using a SanDisk ultra 32 gigabyte micro SD card, loaded with Raspberry Pi OS light version. I'm also using a Pi Camera version 2.1 with the special Pi Zero connector ribbon. For power, I have a UUGear Zero2Go Omini power controller. It's a neat little device that can accept three different power inputs and switch between them regulating the voltage for the Pi. It also senses the incoming voltage and gracefully powers down the Pi when the voltage is too low and powers it back up when the voltage is at a sufficient level. And this is perfect for solar-powered applications. I also have an Adafruit solar charge controller which can power the Pi and charge the battery when the sun is out and switch over to the battery when there isn't any sun. I did customize this component by adding a 4,700 microfarad capacitor which acts as a sort of electron buffer and allows for a smoother transition between power sources. Powering the rig is a 4,400 milliamp LiPo battery and a voltaic six volt 3.4 watt solar panel. I also fabricated a little bracket for the solar panel from some scrap aluminum angle stock I had on hand. It's not shown here, but you saw it in the intro and you'll see it again in the outro. Playing the part of the environmental sensor is a DHT22 temperature and humidity sensor connected to the GPIO pins zero and six for power and to pin 26 for data. For our internet connection, I'm using a Sixfab Cellular IoT HAT with a Twilio Super SIM card. This SIM card is awesome. And then it works pretty much anywhere in the world. For me, located in the US it provides access to the AT&T and T-Mobile data networks depending on whoever has the strongest signal. Now, this modem can use the UART serial port if stacked on the GPIO pins. But I've found that the USB connection method had way better data performance. To use the USB cable for both data and power with a cellular hat, I did have to jumper two pads on the board itself. For the case, I picked up a cheap weatherproof case from my local big-box store for about $6 US. I spray painted it white and drilled two holes in it, one for the camera, which I covered by gluing a thin piece of clear plastic over it. The other hole is for the solar panel connection which I'm gonna seal with silicon. On the inside, I used heavy duty 3M Velcro to stick the components to the side of the container. And that is my self-contained MarsProbe. So what were some of the lessons for me on this project? Well, I learned that there was a decent number of resources out there for Greengrass version one, but not much at all around version two. Hopefully this project will help fill in some of that empty space for somebody. I also learned that with version two, AWS seems to be de-emphasizing the use of lambda functions with Greengrass. And this doesn't hurt my feelings at all. With version one, I often found that using lambda was kind of an extra layer of complexity that didn't really seem necessary. And there are still some rough edges in the user interface and overall experience. The Greengrass CLI is limited not intuitive at all, and it doesn't seem like we can delete old deployments and I had phantom components still associated to core devices that I had long since deleted and re-provisioned. For someone who likes to keep a meticulously clean console, these little leave-behinds really bug me. In fact, to keep a clean console for the recording of this video, I had to hop around to different regions so as not to leave you with a bunch of leftovers on the screen that might confuse people trying to follow along. Overall, this project was a pretty steep learning curve for me. I ran into many roadblocks and dead ends and I wasn't sure if I was doing something wrong. Maybe I was running into a platform bug or maybe I was using some outdated documentation or examples. But that's the learning process. We have to keep trying different things until we land on something that seems to work. So I certainly don't consider this project to represent a reference architecture for a major production IoT deployment, but maybe it helps spark an interest in the topic for someone somewhere. What's next? How about a Mars Rover. I'm Scott Pletcher, thanks for watching. Stay safe, take care of one another and keep being awesome Cloud Gurus. (soft upbeat music)
Info
Channel: A Cloud Guru
Views: 1,322
Rating: undefined out of 5
Keywords: A Cloud Guru, ACG, Cloud Computing, AWS, Amazon Web Services, raspberry pi, raspberry pi projects, raspberry pi 4, raspberry pi zero, raspberry pi os, what is raspberry pi, raspberry pi camera, aws greengrass, raspberry pi setup, connect to raspberry pi remotely, aws iot greengrass, raspberry pi temperature sensor, raspberry pi imager, raspberry pi motion sensor, aws iot greengrass raspberry pi project, internet of things, raspberry pi iot, raspberry pi iot server
Id: Ity2Z03Lp1k
Channel Id: undefined
Length: 32min 31sec (1951 seconds)
Published: Sun Sep 19 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.