 I'm Joel. This is a little story about a project that I started at home with Nervs and Phoenix to kind of help me with a problem that I was working through at home. I'm going to start off by giving some credit to Paul Wilson at Elixir Coffee U earlier this year. I had a really great talk there. It kind of inspired me to get a little more into Nervs and also some folks that I work with, Scott Massio and Dave Shaw, they really motivated me to pick up a side project to kind of learn some things. I am new to Elixir. I'm still learning. I will say, you know, if you find, if you're looking at my GitHub repository or find some slides in here with code on them that could be improved, I am game to pair with you. So if you want to pair a program and try and improve this a little bit, it's all the code is going to be open source. So I'm glad to have anybody help me learn a little bit more. I work at a great company called Cover My Meds. We're located in Ohio. We also have some remote workers. Some of them are here in the audience. We pride ourselves on being one of the greatest companies to work for in Ohio and really, we think, nationwide. And we help, you know, our goal is to help our patients get the meds they need to be healthy. That's what we do. And thanks for Cover My Meds for making it possible for me to be here. Also, I tend to think that I have a pretty amazing family. I was showing Justin and Frank. My wife made this really cool. I love Nerd's t-shirt. Nerd's t-shirt. I love Nerd's, too. So she's great. She's been very supportive as I work on my little pet projects at home. She makes sure that there's, I'm going to take this off. She makes sure that the kids are taking care of for me. And, you know, I think Santa Claus also is pretty fond of our kids. He likes to, every Christmas, he likes to bring some of these things to our home. So we have lots of, we love technology as a family. And early on with my children, you know, I thought these things are great because, you know, I want to expose them to whatever technology I can. And the touchscreens, you know, these are Kindle fires, if you can't tell. We're really, you know, into the Amazon ecosystem and Prime. And there's lots of great learning content and games that they can get on our Kindles, which is all great. When they're younger, you know, they're learning a lot quickly. But after a while, it seems like it started to change the way they play. And what it turns into is sort of the situation where playing is turned into just staring at a screen. Kind of like a lot of adults, we know, probably, but for me, it was a little, a little disturbing to just see my kids staring at the screen all the time, especially, you know, when I'm trying to get their attention, or, you know, I walk, maybe I walk past their bedroom and it looks something like this. And, you know, so I see that they're kind of avoiding some of their responsibilities and I'm trying to teach them to be good, responsible members of the family, take care of some of the things that they need to do at home. So I think about this for a while. And, you know, I remember a friend of mine actually, this is actually not in my house, by the way, just for what it's worth. A friend of mine mentioned that, and I saw this on Facebook, so it's still happening. Some parents approach this problem with a changing Wi-Fi password every day and, you know, a little sticky note or a list that they taped in the refrigerator to tell their kids what chores need to be done before they get access to the Wi-Fi for the home. And this is great. And I think it works pretty well. And actually, you know, you'd say we tried like a paper prototype of this early on to see how it works in my house. And what ended up happening is, you know, we change the password every day, but I've, you know, you saw in the picture earlier, I have three kids and they all have different chores. They get them done at different rates. And so it's hard to manage that. Also, I have my phone and my laptop that are on Wi-Fi that I don't want to have to change my password twice for those. And my wife is really not a big fan of this either. And beyond that, like, think about everything that you have on your Wi-Fi network at home. I have a TV and a printer and things you just, some other random nerves projects, things you just kind of forget about after a while. So I had this idea. I can build a website to show these kids their chores. And on the website, I can have them sort of navigate through the chores and check them off as they get them done. And I can make that something similar to what you might see at the resort here. When you connect to the Wi-Fi here, it prompts you for your name and room number. But then instead, I'll ask them if they got their chores done and which ones they got done and sort of keep track of it that way. Also, you know, this is not a new thing. I haven't invented it. It's a concept called a captive portal. Going forward, I've heard of other people sort of trading Wi-Fi access points, building them on a Raspberry Pi. It's an interesting little project. But I also have been watching these folks at ElixirConf in past years talking about nerves. And I saw how easy it is. It seems like a very easy sort of thing to build an embedded system and start your Elixir app up when the system boots. And actually, I have a quote from Justin yesterday. People shouldn't be afraid of embedded systems development. So I felt a little brave to start this endeavor. But it seemed like the right thing to do. But a little warning. Captive portals and random Wi-Fi access points can be used for evil. So please play nice and don't do any evil things with the stuff that I'm going to show you today. And beyond just my project, I think a web UI is important. So, and the idea that we can have Phoenix apps running on our little embedded nerve systems, it's important because, you know, just like my kids have these little screens that they carry around with them, just about everybody does. And they all have access to Wi-Fi and they all have browsers on them. And it's way easier and more intuitive for our users, at least in my opinion, to navigate a web page because they're used to doing that already versus looking on a tiny little liquid crystal display to read a few messages or a few words and a message to comprehend that or blinking light codes and push buttons. So I think Phoenix apps as an embedded system UI makes sense. And it's a little more about my approach. I want to learn Lixer. I said that earlier. I feel like although, you know, I don't have much experience with it, it sounds like Phoenix is able to perform pretty well on less hardware than say, you know, I'm a Rails developer. So, you know, it's hard to install and run Rails on a little Raspberry Pi like this. It's not very performant. And nerves, you know, I can include lots of additional apps in an Umbrella project. There's lots of talk about Umbrella at the conference here, so I won't go into detail about that. And then start my Phoenix app right as the system boots up automatically. And then nerves also manages other Linux dependencies with build root, which is pretty handy. So I needed a way to segue from talking about more general topics to getting into details. And my friend Dave Shaw, my coworker I mentioned earlier, I was telling him this problem. And he's like, oh, I got you, Joel, just hold on a minute. And, you know, he sends this to me right away. So, and I had to put it in. So the cat on the segue. So that gets me into talking more about details of my Umbrella app. So you can see here I've got firmware, which sort of initializes the system, gets the network set up. There are some Linux dependencies, like I mentioned earlier, that kind of need to initialize. So it takes care of that. I have a Phoenix user interface. That's pretty simple. Basically just displays the chores, and there's some admin functions for adding chores and things. Captive portal redirector is kind of what I called it, but it's basically when you connect to the system over Wi-Fi without some way to redirect that request. I end up, you know, say if you connect and go to elixirlang.org, and I respond with a chore list without the redirect, and it just shows like that's elixirlang.org. That's, for me, it didn't seem like a very, it was kind of confusing, and didn't seem like a very good user experience. So we redirect to the Phoenix app that's running on the device, and I have a chore repository. We'll talk more about that later, and router controls that sort of wrap up some system calls that, because I wanted to separate concerns, and I felt like I could use it in both the user interface and in the Nerves app directly. So to reference those, in Umbrella, in your dependencies, in your mix file, it's a pretty simple pull. This is the Nerves app, so I don't reference the chore repository, say, from here, but I do use the router controls and start the Phoenix app up and running and things like that. So that kind of gets the little preview of the pieces of the application or the project. And next up, talk a little bit about the systems that are available in Nerves. This is the sampling. I think there are more. I mentioned I'm using Raspberry Pi 3, but I did consider some of the other options, but for me, the built-in capabilities for Raspberry Pi 3, it's already got the Wi-Fi adapter built in, and it just seemed like a logical choice. Adding some Linux dependencies I need. So these are listed of extra dependencies that I needed on my system, and Nerves systems are pretty stripped down. There's not much extra shipped with them. It makes them boot fast, makes them small, but it also makes it less useful for me. So I did add some of these dependencies myself. DNS mask is for DNS and DHCP purposes. Host APD is able to basically set up your Wi-Fi access point on your device. IP tables is for creating your firewall rules, and net filter is sort of an extension to IP tables to filter out that traffic some more. And ARP is for some address and resolution purposes, so I can sort of map an IP address to a MAC address, which is very useful for me. So after I find the dependencies that I need to add to my system, and of course this is changing thanks to Justin, he's making it much easier, but for what I've gone through, basically, go find your Nerves project. So in my case, it was Nerves underscore system underscore RPI3, so it's the GitHub repository for the system that I'm interested in. Clone that onto a Linux box, run make menu config to pick a bunch of options, pick these options for the dependencies that I'm needing on my system, and build the system, and then set this very important environment variable so that when you compile your app, it's able to find your new system instead of trying to pull down the one from HEX. Additional info about build root, more specific to Nerves, there's actually three options in Nerves. There's menu config, gives you some access to some native libraries and applications. In my case, that's where DNS mask and host APD were located. There's a Linux menu config version, which gives you access to IP tables and net filter, and busy box menu config, which has lots of handy sort of developer type tools like vim and grep and things like that. So Nerves system BR is GitHub repository that sort of explains this in much more detail. It's got a really great read me. So if you get into the point where you need to build your own system, I would reference that read me, and make sure you read the whole thing because it's kind of tempting to want to sort of skip ahead. It's too long, didn't read sort of mentality, but I think you can find yourself in a little bit of trouble if you try and skip parts of that. So recommend. It's a good read. Build root looks like this. It's actually pretty easy to navigate, somewhat easy to navigate user interface. You can search with the slash forward slash command and bring up a little search box and that helps you find some things when you're done, exit, and you'll be prompted to save your changes and then obviously run the make command to build your new system out. So after that, after I've got my new system, my custom system set up with host APD and DNS mask and all these other great live packages to help me set up my captive portal. There are some configuration files to sort of configure those tools so that they're useful for me. This is a small example of what you might find in DNS mask. Important, one of the more important bits here is that DHCP range kind of gives you an idea of how many IP addresses you can support and you can set up address for router and DNS server if those aren't just your local IP address. This is an example of host APD config. In my case, I just have an SSID called tours underscore net. It's actually capable of setting up more supporting your typical Wi-Fi security protocols. But if you start to turn on things like WPA or whatever, make sure you go back to build root. There may be some other additional options that you need to choose to make those work. Just something to be aware of. And to get those files on my system, I need to sort of have a special directory structure within my product and within my nerves application directory. So there's this root FS additions folder and that's the default location. I think it's configurable. So if you don't like it there, you can move it. But as the name sort of implies, anything under that directory will be placed at the system root when you burn your SD card and it boots up. So that's where you'll find those files and that's how you get them onto your nerves system. And there's this other file here called url init which sort of sets up some startup parameters for your application and nerves and Erlang parameters for things to start up. Some IP tables commands. I'm not sure how interesting these are but for what it's worth, how this application works, you can see we can mark new connections with a 99, a mark of 99. And then the next line down, you can see that we're anything with that mark of 99, we redirect to port 80. And port 80 is where the redirector application is running, that plug application. So any new traffic will get marked with 99 and traffic with the 99 mark gets routed to this plug app which will redirect you to the captive portal phoenix app which presents you with chores. Once you get through the chores and it's not on the slide because it's probably not a good reason for it. But anyway, so once you get through your chores, we can remove that mark from your connection and then the whole internet is available to you again. So that's how it works. My user interface is a phoenix app as I mentioned before. I used the no ecto option when I created this app because the latest version of phoenix and the version of ecto that it supports by default really just has good support for Postgres or MySQL. And from my application that was way overkill for what I needed. So I just turned off ecto for my phoenix app and dealt with that a different way. Again, this starts automatically when nerves starts up. It's a pretty simple application. As I mentioned earlier, I have one controller that basically gets you your first chore, gets you your next chore, and as you get through all the chores it will remove your connection. And so it's pretty straightforward that way. And that's kind of my motto is to keep it simple. Persistence. Like I mentioned earlier, ecto was kind of not a great option. ETS, the syntax is a little weird for me. And amnesia was, it also felt kind of overkill for me. But this really great guy, Chris Dutton of Rosepoint, he's also a nerves core contributor. He built this library called Persistent Storage, which makes it really easy to persist data onto a nerve system, particularly early. It actually, so it'll persist your data to disk, but also keep an in-memory cache of it. So it's sort of quick to retrieve. But it's saved on disk so that it's there between booting cycles. And so that's helpful. So I went with that option. It worked well for me. Here's an example what that sort of looks like. I have a config file that sets up the file in different location in, say, local dev mode versus when it's running on the Raspberry Pi. Nerves actually sets you up, sets your app up in read-only file system, which is good from the standpoint of making sure that it's reliable. And if you lose power, it'll start back up. But it means that you need to put the files that you're changing in a different directory. So that's kind of important here. And then to save and retrieve data, it's a pretty simple key value store. It's really easy to use. So I recommend that. Testing. Testing is important to me. Paul Wilson sort of dealt with this issue in his talk in Elixir Coffee U as well. In my case, I've got lots of operating system calls. And this is an example. I want to test this and write some tests around things at call system.cmd and set up some expectations on what that command returns. So I felt like this is not really a big deal. I've written tests a lot in the past. I'll just go and find a good mocking library and mock up that cmd function. That's easy, right? That's no big deal. So get on Google, search Elixir mocking library. And this is one of the first results that come up. So this got me a little more nervous about my decision because I was afraid of the wrath of Jose's friendliness. But I found a blog post that he wrote, explained it in some pretty clear, concise detail. And he was right, really. You know, what I was trying to do is he puts it as mocking as a verb versus mocking as a noun, which is maybe a good way to put it. I felt like I was just looking at that one function and trying to mock it for my one test. But really what I needed to do is sort of set up this I call it a fake system. It's something that I can stand in for the system when I'm not running in production mode. And setting up for calling these operating system commands, I can't set that up on my Mac. Some of these libraries don't really run on Mac very well. So anyway, config changes between dev and test, I'm sorry, test and production made that really easy to do. And I just have, you know, this is an example of the fake system where if I pass in ARP minus and some specific command line options, it returns a value that's based off of something that I saw in IEX, in an IEX session. So I know what it's supposed to look like. And I can write my test assertions against that. Another really interesting side effect I found of doing this, and it sort of saved me. Justin in his talk yesterday mentioned how he felt like he started to become an SD, a pro at swapping SD cards. I kind of felt that way to you. And I didn't want to keep swapping SD cards for, say, the Phoenix app changes that I was making. So what I ended up doing is actually turning on the fake system when I'm running in dev mode too. So I can start Phoenix up and I can run it. And, you know, it performs good enough for my tests. And I can do a lot of dev work that way. So that's helpful. So I have another segue. I actually have a little bit of a demo that I'd like to do. And I need some volunteers. So I've never actually just full disclosure. I've never actually had as many people in this room on this little Raspberry Pi before. I just have three kids at home that have tried it out. And so I'm a little unsure about whether it'll perform very well or just completely fall flat. Let's try it. So if you look, and if you remember earlier, there is a network connection, a Wi-Fi network called ChoresNet. You should be able to connect that. And let's see how it does. I actually have monitoring sort of that administrative console. I will say that it probably works better on, for me anyway, for demo purposes, if you try and connect with a laptop versus an iPhone or something. But it should still work. And you let me know if it's connecting or if it's I see some connections coming in. No? Okay. Okay. There are some folks who have made it. One person actually has made it all the way through to get to the internet. And now it's reloading. So if there's one person that actually made it through, I wonder if you could maybe raise your hand and nobody? Oh, okay. I'll actually have. So because you're so great at participating, I actually have some swag from Cover My Meds. So thank you, Cover My Meds, if you want to come up. This actually is one of the chores that you have to do up here anyway because you're supposed to give me a big high five, right? Thank you. So anyway, we've got some connections there. At least one person made it through. It works pretty well for three kids at home. So thanks for participating. So back to my slides. This worked out much better at home than it did here. But there is more to the story. So let's go through it. Wrong direction. First off, I exposed the kids to this idea. I turned the Wi-Fi router on. I changed the kindles to connect to it by default. And they're like, wow, this is so cool. Dad, you built this thing, and it helps me know what I need to do in the morning. I can get it done. And I can't believe, like, you made this, really? So they're really into it. They're excited. And I don't know who here has kids. Like, almost everybody, it seems like. They kind of have a short attention span, right? So after they get their chores done, it's like right back to the norm. And then also, days later, it's sort of like the novelties worn off a little bit. So they're kind of, dad, we have to keep using this app. And so that's a little discouraging for me. So I stopped and went back and did a little retrospective, personal retrospective on my project. And I realized something really good came out of it, actually. Yes. I need a badge system. So if only I would have gone to the training on Wednesday. But seriously, the chores are good. They did serve a great purpose. And they got the job done. But there were some things missing. I was just giving them a list of things to do. And nobody likes to be told what to do. That's not fun. So I introduced some fun activities. Like, go give your mom a hug. Go give your dad a high five. Right? That's okay. Yes. I have some interaction with other people. Instead of just going to your room and cleaning and putting your toys away, how about spend some time with a family member? How about go play with the family pet? How about go outside and get some exercise or read a book to your sister? And this was really, really enlightening for me, actually. What ended up happening after this is I found that the kids were spending lots of time playing without the tablets. And they feel they're spending more time together. Like I said, they're leaving the tablets behind. I feel like they're spending more quality time with me, which I enjoy. And it's all because of this little personal project that I started. So it makes me feel really great about doing it. And all those late nights with Frank on Skype or whatever. Thank you for the time, Frank. And the experiment's not over. Like, we have some other things that we want to try out with it as a family. Maybe tie in some positive reinforcement. So beyond just go play and do your chores in between play, but maybe a cookie jar, a Bluetooth cookie jar that opens up when you get your chores done. And you get this little treat. The Bluetooth egg carton. I'm not sure where that fits in, but maybe. And, you know, there's the idea that my wife has. It's kind of like she's got more of an entrepreneurial spirit than maybe I do. But she's curious if we might actually be able to market this and get some folks to buy it off the shelf at Best Buy or something. So who knows? Maybe we'll be on Shark Tank one day. Closing statements. I think hacking on-site projects is a great idea. I'm really thankful for my friends for encouraging me to spend the time and do this. I feel like I know Elixir a little well after this experiment. And it's really good if you can include your family, so you're not sort of leaving them in dark about what you're doing and spending all your time in the basement alone. And even if they take a turn that you didn't expect, embrace it, because that's how you learn. And of course, Elixir, Nervs in Phoenix, great success. Special thanks to the Nervs team. Pretty much everybody on the team. I feel like I've had some interaction with them, and they've been very supportive, not just for me, but the Slack channel and Elixir. They are very helpful for everybody. They're always there and just a great group of people. They're doing some great things to make building embedded systems really and easy. I won't say easy, but really not intimidating. And I appreciate that. Also, my friends or my family for putting them through this and cover my meds and some other folks on Slack who I don't really know their names because you don't show your names on Slack. So there are some aliases. If you see this, thank you for your support. Over the past few months, I know I've asked a lot of questions and everybody's been very helpful. These are the GitHub repositories. The first one is for the main Nervs application. And the second one is for that custom Nerv system that you'll need to run it on. And my Twitter handle, if you did make it through the chores, you should know that one of the chores is to mention me on Twitter. So I'll be looking for that. And that's all I have. So