WEBVTT 00:00.000 --> 00:07.000 Thank you. 00:07.000 --> 00:12.000 So this talk is about how to build something with small thing embedded 00:12.000 --> 00:15.000 Rust and then build something else from this. 00:15.000 --> 00:16.000 This was a site project of mine. 00:16.000 --> 00:22.000 So even though I am developer now working in Clickhouse for a startup, 00:22.000 --> 00:25.000 I did not do this as part of my job. 00:25.000 --> 00:29.000 I also co-founded Dracula, which is something we talked about 00:29.000 --> 00:31.000 in in 2019 about privacy. 00:31.000 --> 00:35.000 And we are also part of a Linux user group in 00:35.000 --> 00:36.000 Akorunia, which is there. 00:36.000 --> 00:39.000 And we are also going to have a conference on free software 00:39.000 --> 00:44.000 and technology, CFT is open if you want to send something. 00:44.000 --> 00:48.000 So first of all, I did this to make an EV charger. 00:48.000 --> 00:51.000 Why make an EV charger? This is the wrong question. 00:51.000 --> 00:54.000 What I wanted to do is learn embedded Rust quickly. 00:54.000 --> 00:58.000 So for me, this has three ways of how to learn anything. 00:58.000 --> 01:02.000 I can read stuff. I can watch others also do things. 01:02.000 --> 01:04.000 But if you are making a project, 01:04.000 --> 01:08.000 it is usually the best way to learn about how things work. 01:08.000 --> 01:12.000 So I could do this with home automation stuff, 01:12.000 --> 01:14.000 like the momentary, community sensors, something like this. 01:14.000 --> 01:16.000 But this is already solved problem. 01:16.000 --> 01:18.000 So it was not really compelling for me. 01:18.000 --> 01:21.000 Or there is also for home automation. 01:21.000 --> 01:23.000 The matter is a new standard that is coming up. 01:23.000 --> 01:25.000 And it is very interesting. 01:25.000 --> 01:27.000 There is not too much land on Rust that I know of. 01:27.000 --> 01:29.000 So I could do something with this. 01:29.000 --> 01:33.000 But the problem is that I also don't know mother. 01:33.000 --> 01:35.000 And I have a rule with side projects. 01:35.000 --> 01:37.000 And my side projects rule number one is that I have to know. 01:37.000 --> 01:40.000 I have to control everything except for the one thing that I want to learn. 01:40.000 --> 01:43.000 So that I don't get distracted by all of the other things that are also variables. 01:43.000 --> 01:46.000 So I thought, okay. 01:46.000 --> 01:49.000 So I have an EV, I could charge it at home for even less. 01:50.000 --> 01:51.000 So why? 01:51.000 --> 01:55.000 Because my parents lived in the countryside in something like this. 01:55.000 --> 01:59.000 So we have a small amount of electricity available. 01:59.000 --> 02:03.000 Less than 2.2 kilowatts, which means less than 10 amps for charging, 02:03.000 --> 02:07.000 which means very slow charging and only at night. 02:07.000 --> 02:10.000 So that we don't disrupt the rest of electronic devices and electricity 02:10.000 --> 02:13.000 things like the fridge and so on. 02:13.000 --> 02:16.000 There are smart chargers in the market. 02:16.000 --> 02:22.000 They usually require physical wiring so that you put a coil from the measures 02:22.000 --> 02:27.000 how much electricity you use in your home in the secret breaker. 02:27.000 --> 02:30.000 And you have to run a wire to whatever the charger is, 02:30.000 --> 02:35.000 which in this case was like 15 meters away and it through the outside. 02:35.000 --> 02:38.000 So you have to make a really lot of mess. 02:38.000 --> 02:41.000 And it's also really expensive for the moment at least. 02:41.000 --> 02:43.000 And in my case, I think that cost matters. 02:43.000 --> 02:49.000 The decisions that led me to have an EV was having cheaper electricity than gas 02:49.000 --> 02:51.000 and cars are depreciating assets. 02:51.000 --> 02:55.000 So you don't really want to spend more on the thing than what you need 02:55.000 --> 02:59.000 because then it doesn't really make sense economically. 02:59.000 --> 03:03.000 And as I said, as I mentioned before, as much chargers are really expensive. 03:03.000 --> 03:06.000 But should they, is the tax so complex? 03:06.000 --> 03:10.000 I'll talk about this at the energy that I promote tomorrow. 03:10.000 --> 03:14.000 The gist of it is that, in my opinion, for this case, 03:14.000 --> 03:16.000 they should probably not be that expensive. 03:16.000 --> 03:18.000 So this is the economics on my side. 03:18.000 --> 03:23.000 In Spain, at home, I can charge less than 18 euros per kilowatt hour. 03:23.000 --> 03:27.000 Usually, on the six months before I did this project, I was charging at about this rate. 03:27.000 --> 03:31.000 So given that I visited my parents, at most twice a month, 03:31.000 --> 03:35.000 then I would save less than 80 years a year by charging at home. 03:35.000 --> 03:39.000 Which means that for me, this must cost less than 160 years. 03:39.000 --> 03:43.000 There's no charging in the market that does this, that cost less than this money. 03:43.000 --> 03:49.000 So it doesn't really make sense to do it. 03:49.000 --> 03:53.000 So first of all, rules to the project. 03:53.000 --> 03:56.000 I have the following rules. 03:56.000 --> 03:59.000 The first one I already mentioned, then make small iterations, 03:59.000 --> 04:03.000 so that I keep myself engaged and I do things that are working one after the other, 04:03.000 --> 04:05.000 and make sure that each iteration provides value, 04:05.000 --> 04:08.000 so that I don't get bored and keep me engaged and continue doing things. 04:08.000 --> 04:12.000 And also, one important thing is that I want to be intentional about 04:12.000 --> 04:16.000 writing things that already work, because otherwise I will get distracted by this kind of things. 04:16.000 --> 04:19.000 And also, I want to learn more of this. 04:19.000 --> 04:23.000 And also, must be functional, so that this is something that I can export as open source 04:23.000 --> 04:25.000 and probably be useful to somebody else. 04:25.000 --> 04:26.000 And also, it's a bit weird. 04:26.000 --> 04:28.000 So if there's two different ways of doing it, 04:28.000 --> 04:33.000 choosing the fastest path is usually the best way for keeping forward with something like this. 04:33.000 --> 04:40.000 So there are some open source projects about doing smart chargers for 04:40.000 --> 04:45.000 forecasts, but they are quite expensive, because most of us usually work in this kind of 04:45.000 --> 04:50.000 projects with the lectures of having nice devices, like a Raspberry Pi or something 04:50.000 --> 04:55.000 that has a full OS that can parse XML with libraries that already exist. 04:55.000 --> 04:56.000 And they're really nice. 04:56.000 --> 05:00.000 But when you try to also compound it with the economics of the things, 05:00.000 --> 05:05.000 then it gets expensive for something that doesn't really exist. 05:05.000 --> 05:10.000 So what I did is step one, I bought the dumbest and cheapest chargers I could find. 05:10.000 --> 05:14.000 This was 60 bucks, so that I could understand it. 05:14.000 --> 05:18.000 The second step, this is the thing, so that I could see what's inside. 05:18.000 --> 05:20.000 And it's really not much. 05:20.000 --> 05:24.000 There's a bunch of wires, I measured that they could support the chargers. 05:24.000 --> 05:29.000 And I was not being, it was not less expensive, because it didn't work. 05:29.000 --> 05:33.000 And it didn't have enough of the hardware. 05:33.000 --> 05:39.000 And it has this small chip on the top right that is just sending a post, 05:39.000 --> 05:46.000 motivated with a post to the car to let it know how much it can charge. 05:46.000 --> 05:52.000 In this very box, I could fit an SP32 as you can see there with the debug wires that already existed 05:52.000 --> 05:54.000 in the board, I was surprised by that. 05:54.000 --> 05:58.000 So I could even do it like that. 05:58.000 --> 06:01.000 But let's not get ahead of her shots. 06:01.000 --> 06:02.000 So how do we split this? 06:02.000 --> 06:06.000 First of all, I will need a wattmeter to measure how much energy is at home. 06:06.000 --> 06:13.000 And then this is, I think, that can be built in an SP32, which I can use in battle thrust for. 06:13.000 --> 06:19.000 And then I need something that can tell the car how fast it can charge. 06:19.000 --> 06:22.000 This can be something using some of these standards, or something else. 06:22.000 --> 06:26.000 And it is something else I'll talk about it in five minutes after. 06:26.000 --> 06:30.000 So my experience with ESPRS, I like it. 06:30.000 --> 06:36.000 This is currently an expression product, so it is official by the people from the SP32 community. 06:36.000 --> 06:40.000 It's less mature than the C++ SDK. 06:40.000 --> 06:46.000 But the experience is so much better, because everything with cargo just works. 06:46.000 --> 06:50.000 And this is one of the things that I want to highlight about how good the ecosystem in Rust is, 06:50.000 --> 06:54.000 because with cargo build and cargo run, you just have everything. 06:54.000 --> 07:00.000 Well, when you get to dependencies, you will get all of the things necessary for flashing the device, 07:00.000 --> 07:03.000 and for selecting which USB device it is, and so on. 07:03.000 --> 07:05.000 And this works in all of these OS's. 07:05.000 --> 07:09.000 I tested on, if you have them, because I wanted to see if the experience was as good. 07:09.000 --> 07:13.000 And it is, with C++, it's not as much. 07:13.000 --> 07:14.000 I can tell you. 07:14.000 --> 07:16.000 There's two versions of this. 07:16.000 --> 07:19.000 In case you want to do something with this, there's the IDF version, 07:19.000 --> 07:21.000 which is the C++ SDK. 07:21.000 --> 07:27.000 It is nice because it allows you to use the full STD Rust, which is very convenient. 07:27.000 --> 07:33.000 And it has all of the nice cities about being able to work with the normal type memory, the Wi-Fi, the TCP stack, 07:33.000 --> 07:34.000 and so on. 07:34.000 --> 07:40.000 It also has an embedded HTTP server, which is very convenient for my case. 07:40.000 --> 07:44.000 And then there's the other bare-one project, which uses no STD, 07:44.000 --> 07:48.000 and you have to build your own concurrency planning. 07:48.000 --> 07:50.000 There's an embassy and other projects. 07:50.000 --> 07:56.000 For that, and then you have to roll out your own TCP implementation, HTTP and so on. 07:56.000 --> 08:03.000 So I used the IDF version for my first iteration of this, because of the number one and two. 08:03.000 --> 08:07.000 And I initially was most of the hardware in the main. 08:07.000 --> 08:14.000 So first of all, this was just a toy project, and then I started to rewrite things into something that worked with the lifetime, 08:14.000 --> 08:19.000 so on for each of the parts, because I wanted to create a set up mode to be able to change the Wi-Fi connection, 08:19.000 --> 08:22.000 and so on, we have having to re-flash the device. 08:22.000 --> 08:27.000 And I even allowed to hot-black an SPI LCD screen, because I wanted to see things 08:27.000 --> 08:32.000 while not connected to a laptop to see, to try to debug when things were not working. 08:32.000 --> 08:39.000 So this is the layout of how, which things I did first and which things were pushed forward. 08:39.000 --> 08:43.000 The last thing was implementing a web hook, you will see what in two slides. 08:43.000 --> 08:47.000 And this is what the hardware actually looks like when plugged in. 08:47.000 --> 08:55.000 The thing you see on the top right is just a current transformer, that measures the jumpers that are running through the line, 08:55.000 --> 09:05.000 and then there's the ESPN as small voltage converter to run to three volts DC. 09:05.000 --> 09:09.000 So now what? I already had this. 09:09.000 --> 09:14.000 I could use the car up manually on the phone to calculate the amps and do it manually, 09:14.000 --> 09:18.000 but this is very cumbersome. I did this for a few days. It didn't really scale. 09:18.000 --> 09:24.000 Then I built a script in Python that I run from my laptop, 09:24.000 --> 09:30.000 and from there I used the car API to tell it how fast it could charge. 09:30.000 --> 09:36.000 But that wasn't convenient. I had to remember to have the laptop on to have the script running, 09:36.000 --> 09:41.000 and I just didn't all the time, so I built a back end in Rust. Why? 09:41.000 --> 09:46.000 Well, first of all, I need to do something that can get an API, 09:46.000 --> 09:49.000 and preferably with this properties. 09:49.000 --> 09:53.000 It's easy for me to, if it can just deploy a single static binary, 09:53.000 --> 09:56.000 and if it's configured with a Tamil file or something like that, 09:56.000 --> 10:01.000 and then I wanted to have a database to store all of the energy logs for all of the times, 10:01.000 --> 10:06.000 to have an historic versions of how much energy was being used and so on. 10:06.000 --> 10:11.000 I decided on rocket, because it had these things and also type level guards, 10:11.000 --> 10:16.000 which I believe are amazing to ensure that you are authenticated and so on, 10:16.000 --> 10:18.000 and also ready to make it so easy to implement. 10:18.000 --> 10:21.000 So I don't get those by somebody random on the internet, 10:21.000 --> 10:24.000 and then logging is built in, which is nice. 10:24.000 --> 10:28.000 So this product uses that, and then I even, 10:29.000 --> 10:33.000 one of the iterations of the words was just, I also wanted to see how much energy was being used, 10:33.000 --> 10:36.000 and then I ended up even rendering an SVT with the energy usage, 10:36.000 --> 10:41.000 so that I could see things of it a bit more interesting. 10:41.000 --> 10:44.000 I only had one piece missing, which is the main point of the talk, 10:44.000 --> 10:47.000 which is how do I communicate with the car? 10:47.000 --> 10:52.000 Well, there's basically two main standard ways of doing this. 10:52.000 --> 10:57.000 One of them is sending a pulse with modulation over one of the wires 10:57.000 --> 10:58.000 in the charger. 10:58.000 --> 11:01.000 These are twice physically out there in the charger's dimension. 11:01.000 --> 11:06.000 There's also an ISO, which allows you to send XML over Ethernet over one of the wires also, 11:06.000 --> 11:10.000 which is cumbersome, because also it requires you to send Ethernet frames, 11:10.000 --> 11:13.000 which is one more level of complexity. 11:13.000 --> 11:16.000 It is, the modem itself is not cheap. 11:16.000 --> 11:19.000 I mean, not cheap for embedded standards. 11:19.000 --> 11:25.000 And the modem, I believe, is not implemented in open-source or I didn't see it in an embedded fashion. 11:25.000 --> 11:29.000 These things are implemented, but as I mentioned, they require expensive hardware, 11:29.000 --> 11:33.000 which makes it not a cost-effective in my case to use. 11:33.000 --> 11:38.000 Also, the IUC standard, the lowest you can send is 5 amps, 11:38.000 --> 11:44.000 and since the most I had was 10, I already was halfway out of the range, 11:44.000 --> 11:46.000 so of what I could use. 11:46.000 --> 11:50.000 Then there's a car vendor API, which is what I ended up using, 11:50.000 --> 11:52.000 because it was cheaper for me to go this route, 11:52.000 --> 11:58.000 but I didn't want to commit to only needing to do one of these. 11:58.000 --> 12:01.000 So I wanted to make this a sensible for other people, 12:01.000 --> 12:05.000 and maybe in the future for open-source chargers. 12:05.000 --> 12:09.000 So what I did is in the crate, where I built the backend, 12:09.000 --> 12:13.000 I created this fairing, a fairing is a thing that you can put in rockets, 12:13.000 --> 12:19.000 so that it attaches on every request or an ignite or any other parts of the life cycle. 12:19.000 --> 12:22.000 And it does most of the heavy lifting, 12:22.000 --> 12:24.000 and you just have to provide two different things. 12:24.000 --> 12:28.000 One is basically this EV charge handler trade, 12:28.000 --> 12:32.000 which is so first of all, the fairing is really simple, 12:32.000 --> 12:35.000 only connect what you do, what this does is, 12:35.000 --> 12:41.000 I just guard against only doing one change over the car at a time, 12:41.000 --> 12:43.000 so that even if I have multiple requests, 12:43.000 --> 12:47.000 only one of them will go to the car, the others will just measure the energy, 12:47.000 --> 12:50.000 go to the log, but then do nothing else. 12:50.000 --> 12:53.000 That's why I have a mutex here. 12:53.000 --> 12:59.000 And then this is the charge handler implementation that you will have to provide for any other charger or any other API. 12:59.000 --> 13:03.000 Just have to do four methods, which is what? 13:03.000 --> 13:08.000 You're saying it's some name, the distribuile, then you have to return, 13:08.000 --> 13:14.000 whichever kind of structure you want that we will keep on the fairing. 13:14.000 --> 13:20.000 Then something that gets the state, so that you will have some internal state that you can rely on, 13:20.000 --> 13:25.000 and then a function to request changing the, changing the apps. 13:25.000 --> 13:30.000 The state also has to deal with four things, which is whether the car is charging, 13:30.000 --> 13:33.000 because otherwise it doesn't make sense, so we will do nothing, 13:33.000 --> 13:39.000 and also some other small things, and whether the car is nearby, 13:39.000 --> 13:42.000 because if you can already know how far away it is, 13:42.000 --> 13:47.000 then we can rate limit this, and for example, the car is in another town, like 500 kilometers away, 13:47.000 --> 13:54.000 then you will say, okay, let's wait for five hours, because you will not go that far to wherever it is. 13:54.000 --> 13:57.000 This is the current interface. 13:57.000 --> 14:04.000 This is the SVG, and some of the parts that you can see there are times where maybe the system crashed, 14:04.000 --> 14:07.000 or it was not connected or so on. 14:07.000 --> 14:11.000 And then I have a couple of criticisms of rocket, what I used. 14:11.000 --> 14:15.000 In general, I think it was a pretty nice and pretty easy to build, 14:15.000 --> 14:23.000 but a think is a bit hard, because, well, in general, maybe this is something that happens with other parts of trust. 14:23.000 --> 14:28.000 But in rocket, even though the requests are handled asynchronously, 14:28.000 --> 14:36.000 it's not easy to move part of the work to outside the life cycle of the request and do it in another set. 14:36.000 --> 14:40.000 We had to roll out on your own a lot of different things. 14:40.000 --> 14:45.000 I managed to do it with static life time, so it was a bit cumbersome, 14:45.000 --> 14:49.000 so I didn't end up pushing it to the source code. 14:49.000 --> 14:54.000 And then there's the last part of this, which is this was a side project. 14:54.000 --> 14:58.000 It's really efficient for doing this, how much does it take? 14:58.000 --> 15:01.000 Well, the short answer is hyperlifias. 15:02.000 --> 15:03.000 Why? 15:03.000 --> 15:08.000 Well, this was basically a one-month total time for all of this, 15:08.000 --> 15:10.000 in two weeks I had things already working, 15:10.000 --> 15:14.000 and two weeks side project commitment level, 15:14.000 --> 15:16.000 meaning not a lot of time. 15:16.000 --> 15:20.000 And also, I believe that more than efficiency, 15:20.000 --> 15:23.000 the interesting part about this is whether this is enjoyable. 15:23.000 --> 15:25.000 And I believe it is a lot more than in other languages, 15:25.000 --> 15:28.000 because compile them errors are very useful once you understand them, 15:28.000 --> 15:30.000 because the compiler is really great, 15:30.000 --> 15:34.000 but highlighting the different things that you could be wrong about. 15:34.000 --> 15:36.000 So there's less runtime panics. 15:36.000 --> 15:38.000 There's a bit of them, but also in the embedded controllers, 15:38.000 --> 15:40.000 usually when you have a panic, 15:40.000 --> 15:43.000 the handler can just restart the microcontroller from scratch. 15:43.000 --> 15:45.000 So even when you have a problem, 15:45.000 --> 15:48.000 it's not really something that you can't get away from. 15:48.000 --> 15:50.000 You can, the microcontroller will restart, 15:50.000 --> 15:53.000 and if it's not in a very weird situation, 15:53.000 --> 15:57.000 you will just start from scratch, from a working state. 15:58.000 --> 16:00.000 So you can recover. 16:00.000 --> 16:02.000 And then it's very fast to compile, 16:02.000 --> 16:04.000 especially compared to the C++ projects, 16:04.000 --> 16:06.000 depending on how you build the compilation units. 16:06.000 --> 16:10.000 This is something that cargo really does very well. 16:10.000 --> 16:14.000 So there's a bit of future work with this. 16:14.000 --> 16:17.000 Part of this would be re-implementing the wattmeter part 16:17.000 --> 16:19.000 with the no-SD version, 16:19.000 --> 16:23.000 because currently the version, which is the idea, 16:23.000 --> 16:29.000 the C++ SDK, has a problem that it is quite big. 16:29.000 --> 16:33.000 The full binary takes a while to flash, 16:33.000 --> 16:35.000 takes maybe a minute and a half, 16:35.000 --> 16:38.000 because it has to bundle the Wi-Fi, 16:38.000 --> 16:43.000 the handling of all the DCP stack, 16:43.000 --> 16:46.000 the web server, and other things that I am not using, 16:46.000 --> 16:48.000 like Bluetooth and so on. 16:48.000 --> 16:50.000 So by using NoSD, I could cut down on this, 16:50.000 --> 16:52.000 because more things would be in-rust, 16:52.000 --> 16:56.000 and it would be easier to just not include as dependencies. 16:56.000 --> 16:59.000 And also, it would be nice to make, 16:59.000 --> 17:02.000 and I also, 15-1-1-8 charger, 17:02.000 --> 17:04.000 which is the one that talks XML. 17:04.000 --> 17:07.000 In ESP32, I believe, instead of using a Raspberry Pi, 17:07.000 --> 17:10.000 but this is something that I didn't see, 17:10.000 --> 17:14.000 yet, as part of all of this, 17:14.000 --> 17:18.000 because all of them just require you to build full OS, 17:18.000 --> 17:20.000 I mentioned in the beginning, 17:20.000 --> 17:24.000 and then it's a lot of work for only for that. 17:24.000 --> 17:26.000 And that's it. 17:26.000 --> 17:29.000 Yeah. So any questions? 17:34.000 --> 17:36.000 What's I to fast? 17:43.000 --> 17:47.000 In understanding your return on investment trade-offs, 17:47.000 --> 17:51.000 how many thousand kilometers a year do you drive? 17:51.000 --> 17:54.000 How many thousand kilometers a year do you drive to 17:54.000 --> 17:57.000 understand your trade-offs for your investment? 17:57.000 --> 17:58.000 How many thousand dollars? 17:58.000 --> 18:00.000 How much do you drive? 18:00.000 --> 18:03.000 How many thousand kilometers per year? 18:03.000 --> 18:06.000 Okay, so I usually drive around 30,000 dollars. 18:06.000 --> 18:07.000 Okay. 18:07.000 --> 18:08.000 How many kilometers per year? 18:08.000 --> 18:10.000 That's a twice average. 18:10.000 --> 18:11.000 Yeah. 18:11.000 --> 18:12.000 Okay. 18:18.000 --> 18:21.000 Any more questions? 18:21.000 --> 18:23.000 Yeah. 18:23.000 --> 18:27.000 Which type of ESP did you use? 18:27.000 --> 18:28.000 Which type? 18:28.000 --> 18:30.000 Did you ever mention the binaries? 18:30.000 --> 18:31.000 Get quite big. 18:31.000 --> 18:33.000 Did you ever hit the limit of the flesh? 18:33.000 --> 18:34.000 Yeah. 18:34.000 --> 18:36.000 Which type of EVSE? 18:36.000 --> 18:38.000 Yeah. 18:38.000 --> 18:40.000 Oh, the type of ESP I used. 18:40.000 --> 18:44.000 I used the ESP32, nothing else after that. 18:45.000 --> 18:47.000 The risk five days. 18:47.000 --> 18:48.000 The risk five days. 18:48.000 --> 18:49.000 Yes. 18:51.000 --> 18:52.000 No. 18:52.000 --> 18:54.000 It didn't hit the limit of flesh ice. 18:54.000 --> 18:55.000 But yeah. 18:55.000 --> 18:56.000 That is a concern. 18:56.000 --> 18:59.000 That's actually part of why I wanted to use the 18:59.000 --> 19:01.000 the No. STD version because that would be 19:01.000 --> 19:04.000 leaving me a lot more room to play with other staff 19:04.000 --> 19:06.000 in building my own things. 19:09.000 --> 19:10.000 All right. 19:10.000 --> 19:11.000 If there's no more questions, 19:11.000 --> 19:14.000 can we thank San Diego? 19:14.000 --> 19:15.000 Thank you.