Kassian's IoT Hour
Let's dig into how you can use Serverless to supercharge your IoT projects! We'll walk through setting up a remote sensor and LED with Cloudflare Workers, Workers KV, and a Raspberry Pi
Transcript (Beta)
I am Kassian and welcome to the IoT Hour. So today what we're going to be doing is we're going to be working with Raspberry Pi like so and what I've got installed on it already is a Node.js runtime 14.8.
I also have Redis installed and I'm going to use the PubSub and I have Argo Tunnel installed and so what I'm going to do is I'm going to use the PubSub ability from Redis to get this Raspberry Pi talking and then next week we're going to add more Raspberry Pis.
I had to order some power supplies.
My Raspberry Pi is being quite finicky as to which power supply it'll use so right now I only have the one running on this power supply and so next week we'll get them to talk to each other but this week we're going to get this one started as the main hub of the Raspberry Pi kind of network that we're going to build so let's get started.
I'll share my screen like I usually do. All right so right now what we're looking at is the Redis documentation and so we're looking at the PubSub for Node.js Redis and so what we're going to do is we're going to create a client that will subscribe to a channel and yeah so we'll subscribe to your channel and then what we'll do is we'll write a worker that when you write an HTTP request will make a message and send an HTTP request to the Raspberry Pi which will make a PubSub and so then what'll happen is other Raspberry Pis will subscribe to the Redis instance on this Raspberry Pi and listen for notifications.
So let me walk you through what I've done to this Pi so far. What I've done so far I set up here.
I've done all this. I've installed Raspbian. I've set up Wi-Fi and SSH.
I've done all this. Gotten started with installing Node, installing NPM.
I installed the Cloudflare daemon so it's running to push .nodebotanist.
You can see here so right now it's just returning a JSON response. What we're going to do is we're going to write a worker that will ping it and it will send a message.
Now the question would be like why would you write a worker when you've got everyone kind of running and the reason for that is I don't want to go back to the origin every time.
I want the worker to handle going back to the origin so I want the basically I want the response to come as quickly as possible to say a customer.
If I was building a distributed system of IoT devices, I would send them to a worker which would be faster for them to get a hold of and get the response back from and then the worker would have the job of going back to the origin and actually making the request.
So that's why we're doing this with Argo Tunnel and workers and not just you know say Argo Tunnel.
So let's get started with writing our Redis request.
So what I'm going to do here is I'm going to actually want to open VS Code and I'm going to use SSH.
This is a host so we're going to say push i iot push .local and we're going to actually put i at oh a hash in there that I shouldn't have.
Close this window. Try that again.
Okay so it's setting up VS Code on the Pi which is kind of nice that way we don't have to worry about installing it ourselves and what we're going to do is edit our code through VS Code from here just because I like the experience a little better.
You can use Vim or VI or whatever you want to use. I'm not going to get in that argument about which is better because they're all good and so yeah I just like VS Code.
Let's install and while it's installing actually what we'll do is we'll set up a new tab here on my local machine.
I'm going to code. I'm going to iot hour. Okay so we got IoT dashboard and it showed temp so what we're going to do is we're going to say wrangler first mpli g.
Remember the domain slash wrangler.
Okay so that's all installed.
Made sure it's up to date and then we're going to say wrangler create and we'll call it push.
Wrangler net.
No not wrangler. Sorry about this.
Just had a blank out there. Wrangler. Ah wrangler generate.
There we go. Lots of weird notification noises from all over the place.
Wrangler generate and we'll say iot push.
Okay so now we got this as well.
Let's see how it's going. Okay cool. So we've got iot push to local.
We're going to go to files. We're going to open a folder and we're going to open our iot push folder here.
Okay I'm going to ask for my password again.
Nope did not. All right. I don't know why this file is called index .html.
It should be index.js. That's very strange.
Rename and we'll go into the pi.
So the server's running again.
Okay so we've got our server here. This is the other reason I wanted to use VS Code.
We can leave our server running. Actually you know what?
It's better. What we can is we can close this and then we're going to npm install global nodemon.
And then this way when we edit something in VS Code and save it, it'll reload the server which would be pretty handy.
Okay I just installed it though.
Well that's strange.
I did one thing way earlier.
Okay there we go.
I just nodemon. I changed the npm install prefix for global so that it would have access to get around the e-access issue.
So now it'll change every time we edit something here in VS Code.
For instance if I say change this message to hi and I save it back up here.
You see it's made the changes and when I go into here and I go push in the bot nest refresh.
Yes it's hi. So that's our dev setup right there.
All right so now we've got our dev setup. Let's start messing around with Redis and getting this PubSub set up.
Actually we are going to have to close this because I want to install my Redis.
Okay now it's running and we have access to Redis.
Redis equals require. All right I've got Redis and make sure this runs properly.
Yep cool. So right now what we're going to do is we're not going to do any smart routing.
We're just going to say every time it pings send a message saying you know someone connected.
And then we'll start adding things like you can send data between pies and things like that.
So we'll start out very simply and build up that way.
Hopefully this makes sense to everyone. I will also put all of this code in the Cassians IoT Hour GitHub repository under nodebotness slash cassians dash iot dash hour.
That way you'll be able to access this code after this airs. So well it's airing live.
We're done here. So now we've got Redis. So let's go into our node Redis and what we've got is const publisher and const subscriber.
So we are going to create publisher.
We don't need any options because everything's the default right now.
So let's check okay everything's running correctly and then okay.
So we're going to subscribe or not subscribe a channel. Oh we're going to publish.
I see. We're going to we're going to be doing one of the publishing. So we're going to publish or not publish a channel a message.
So okay. I see why it does both.
We're actually going to do both as well. We're going to call it temp subscribers so that we can emulate another pi listening.
And so on our request listener what we're going to do is um here we're going to pub sub publish and color channel iot push just to keep things consistent.
So we're going to send the message.
Message published back to the user.
Okay what we're going to do now is it says the server is running.
We're going to check it.
It unbuttoned us. All right sweet. So we are publishing onto a redis instance.
We're not getting any errors or anything like that. So that's cool. All these semicolons keep coming.
They're not mine and no I don't want to have that argument with y'all.
Anyway it makes me think I'm writing rust and then I do rust things when I use semicolons.
So that's my reason for not using semicolons in javascript.
It's not the best but you know it is what it is. All right so we've got our publisher.publish.
Right so now what we're going to say is temp subscriber on message.
We're going to open up a function which I believe takes a channel and a message.
we're actually going to do this.
So all right cool.
So now we've got temp subscriber on message, channel message, and we're going to say temp subscriber dot subscribe to iot push.
Okay now we go here.
Server is running and when I go here and hit refresh what it should do is not just say that but channel iot push message hello.
So now we've got pub sub working on our raspberry pi and we can call it from argotunnel.
So what we're going to do is create write a worker to call this extension.
So that way again we don't have to go back to the origin for the user.
The user can just get back a response immediately while the pub sub happens in the background and goes back to the origin in the background.
We use an asynchronous call to do so. So let's go into our local folder.
We're going to open up vs code in here. Okay so all this and then next.js.
Okay so return response hello worker.
So what we're going to do actually is we're going to say because now this does not allow asynchronous calling.
So when we run this what will happen is it will wait until the call has come back.
So we'll go back to the origin but we can work on this later to make it a little more asynchronous.
So the next thing I need to do is I'm going to tab out of my Cloudflare account on another screen.
No that's not what I wanted really.
What I wanted to do is over here. There we go. And we're going to log in.
I'm going to get my account id so that I can get all that settled.
Manage workers.
Okay I can't let me copy. Wrangler.toml.
I'm going to put in my account id. Save this and close it. All right now what we're going to do is worker wrangler preview.
Okay now in my other window we'll pull it back into this window.
It opened up a new window.
You hear me slamming my mouse around.
So Cloudflare Workers opened up this tab in Cloudflare Workers and it says hello worker which is good because that means hopefully what we'll see in our return when we go back into here is iot push message hello.
So now there's three so let's see if we get a fourth when we run it again.
We did so it is getting it from the worker.
So we now have a worker that is pushing a PubSub message or well it's pushing an HTTP request to raspberry pi which is then setting up a PubSub message.
And what's really cool about this is we can set this up on multiple devices not just raspberry pi.
It's basically anything I could take that can subscribe to the Redis PubSub.
We'll be able to use this. So what we're going to do next is kind of flesh out the HTTP server and kind of allow us to send our own messages and we will allow to send JSON and that way we can kind of send like a data back and forth.
For instance the other raspberry pi I have has the light grid on it.
We could send colors back and forth from the main one and whenever there's a color this raspberry pi with the lights will be listening and will light up that color.
So you can kind of flesh this out a little bit as we go.
So let's start with our server. So our server is very simple. We don't really have anything any routing or anything like that.
We just kind of have this one setup.
So what we're going to do is we're going to change that. I remember correctly.
That is not what I'm looking for.
Here we are. Okay.
So we're going to add our router. First we're going to close the server for a second.
I've got router.
I'm going to put this under HTTP. Okay.
Anyway. So now we've got all this. What we're going to do is we're going to go back here and this is router rec res final handler rec res.
Okay. So we're going to copy this line here.
We're going to take our server.
We're going to kind of oh that's not what I need to do.
So we're going to do this out.
Delete it. We're going to move it here in a moment. Paste this.
Okay.
So oh right. We've got to establish it. So router in uppercase and then down here router.
New router or just router?
Oh wow.
I'm working the rest a lot lately. So okay. Okay. It says the server's running.
I don't think it'll actually do anything if we go to refresh it because yeah.
Anyway. So oh no monop crash. Final handler is not defined.
Okay. Oh I see.
We don't need to add a final handler if we don't want to. So we can just close this.
I think the server will be working again but I don't think it'll do anything again if we refresh.
Okay. So now we're going to go back here and we're going to go back to my gateway.
Arguing callback is required. Yeah function handler router.
114. Because it does require a callback. Let's see.
So now I don't get my gateway but I don't get anything back because it's not actually doing anything with our rec and our res.
So now what we're going to do is we're going to add for router get res.
Take this code and copy it here.
And then message message published.
And we'll go back to our server channel. Now we've got it back to where we wanted it at the beginning but with a router.
So now we can kind of mess around with the router and allow different messages to go different places.
For instance we'll channel to iot push route.
And then what we'll do is we'll say router get push. Okay so now what we're going to do is we're going to pub sub sub publish.
We'll say 32 point.
It's about right. Celsius degrees. Right. It sounds like a normal temperature for outside.
So and then JSON. And we'll do this back ticks.
Message.
For sure.
Yeah.
So now we go over here.
Server is running to our browser. And we'll say push.net botanist slash temp.
Yeah. JSON and we go to our. Oh I said it to a different channel didn't I.
Yes I did. So let's go over. Nope. Data.
Again refresh.
Fresh here. Temperature to descent. Temperature to descent. So what we've got now is we've got a functioning Redis server that can take in different routes and send to different channels.
And so you have to subscribe to all these different channels.
So what we're going to do next is we are going to flush this out so we can actually send the data as part of the request.
Also we want these to be post requests because we are adding data to a database.
We don't necessarily want these to be get requests.
So let's do that. First we're going to do. I'm going to say router.get.
It stays the same but we're going to change here's router.post. So when we go back here now and we refresh it's not going to do anything.
Right.
So we're going to go to Cloudflare workers. We're going to do testing. We're going to post.
Yes.
Push. Botanist.
Test.
It's my Hello Worker and we go back here. IoT message main. Yes, that's because I didn't add temp.
Test.
Vaccine.
Terminal. IoT push message main. Strange. Why isn't it running? Getting more pushes on message.main.
Oh, I think that's because of. I just realized I don't think.
Oh, of course my install is fantastic.
So now I think.
Fantastic. So now we're going to do is we are going to do collections, new collection.
IoT push collection.
Create. Request name.
Post to temp. Push. So the request URL is going to be a post request.
I'm going to remove this. Here. Yeah, I can see.
Yes. Oh, we also need to get the worker going.
I knew I forgot something. We'll get the worker going as well.
Um. OK, so this is working.
This is OK. Awesome. So now what we want to do is we want to get the worker posting to temp data.
So we'll go this way to our worker. That's right.
All right, that's in and then we will. Doesn't seem to work.
All right, so that's not it.
Been a while. Method posts.
Always different. OK, hello, worker.
Oh, that was not the right worker, but let's check that we got another.
We did get another temp push. Let's make sure that was from the right source.
OK, hello, worker.
And then when we go to that, we're sure there's not five. So now we've got our worker making our request, our post request to.
To our API, so.
Let's start fleshing out what a home automation Redis database would look like.
So not just a PubSub, but also database so that we can see like historical temperature data, things like that.
So we're going to watch Node Redis and we're going to go from PubSub to.
There's a one-to-one mapping Redis commands, so we'll open up Redis commands, close this for now, close router for now, close using fetch, close this conflict workers.
OK, so we've got a bunch of commands that we can.
This isn't exactly.
What we're looking for.
OK.
All right, so we're just going to use for now we're going to use just like set.
OK, so we're going to use hs set and I'm pretty sure this is going to cover here, hm set.
All right. So let's do first, let's allow the user to send in the body of their requests.
And.
A temperature that can then be used to so we can send them a temperature along with it.
And so body, body. We're going to send on like a post, we're going to send a body.
And it's going to be JSON stringify.
OK.
We create a temperature that will be a math.for. Math.random.
And 12.
Plus.
13.
No, we'll say. Yeah, that's a 20. So the minimum is 20 and the maximum is 32. So we're going to send a random.
A random temperature every time.
So we're going to save this. That's our worker.
And so we want to set up our server to actually take in this data.
And so that's here. HTTP request objects.
So.
Why did I forget how to do this?
Should be indirect that body.
So.
If that works.
It's running right here to. Where was my. Oh, right. Again. OK.
Not coming back this time. All right, because it's awaiting the fetch.
See what happens if I take out the wait.
OK, so something's going on with the fetch request.
Let's figure out what that is.
It's stalling.
Let's figure out why that is. Ah, correct, that body is undefined, which means it's probably erroring out on the JSON parts.
Come on.
Right. Cool.
So we're going to do is we're going to implement this inside this setup.
That.
And then we're going to.
This. Here. That's not what I want to do.
This.
Running.
Send. There we go. Kind of. Add gateway. All right. Unexpected end of JSON input.
Oh, right.
Still that gateway.
I've crashed. OK. OK. That's fine. Right. And we're going to have to.
If. Still stalling, which is strange.
Oh, these are query params. These are not. OK, that's why.
All right. All right. Body. Body. OK. I can remember where everything is.
OK.
I stop it. Or can I. Awesome.
OK, so it was because we didn't have a body. OK. Message temp 3.2. OK, so what we want to do is we want to extract the temperature.
Here. Oh, right.
All right. All right. All right. All right. All right.
Let's. Save it.
We're still running.
Is. This man will send it. Not getting anything back. He did publish.
We're not getting anything. It is still publishing, but it's still not going through.
Which is strange. We just need to put this.
Here. Running.
Temp 3.2.
Temp 3.2. Temp 3.2. Temp 3.2. Temp 3.2. Temp 3.2. Temp 3.2. Temp 3.2. Temp 3 .2.
We're going to do. Temp 3.2. Temp 3.2.
Okay.
Okay. Okay. That's something at least. Okay. Okay.
Okay.
Okay.
Okay.
I got a message there. It was important, but it seems. All right. As we were.
All right. Add gateway.
Oh.
Okay. Let's see if I get it because it's not restarted yet.
And again.
Okay.
But I have that. Hmm. That's so strange.
The quotes are still there though, which probably shouldn't be. Hmm.
Add gateway.
Yeah. So that's not it. Oh, Jason.
And then I need to go here.
And refresh the server. Running again. Okay.
So it was all bad. Whew. That was a lot. Cool. So we have got. A Redis instance that is.
Taking in data. And pub subbing it. And so next week, what we're going to do is we're going to start saving temperature data so that we can have like a series of temperature data.
And then we're going to have like a, we can make a graph.
Although you've seen my. Experimentation with graphs. We're going to have some fun with that.
And. So. That's going to be in our, our next eventual also be talking between two Raspberry Pis.
There is a power supply on its way.
For next week so that we will have two Raspberry Pis and they'll be able to talk to each other.
And we'll be able to do the, the, the, the, the, the, the, the, The, the, the, the, the, the, the, the, the, the, the, the, the, And we will be doing all that.
Next week. So for the rest of the time, I think I'm just going to clean up code.
Pardon me and get this ready to set into the IOT hour. So. All right, so we've got this all cleaned up.
It's actually pretty cleaned up.
All right, semicolons sitting around, and then you know what else I'll do?
So...
I think it's using tabs now.
Yes, it is. Awesome. Awesome. Awesome. Oh, no, it's using all spaces, so I'm going to have to...
Fantastic.
It just did it all for me.
All right, though, these are two in. Okay.
It's just about ready to go into Cassian's IoT Hour stuff.
So what I'm going to do is I'm going to get that going while we...
Okay, so... Not really what I wanted.
You know what?
That's not what I wanted either. Goodness. Off my game today when it comes to that.
Here we go. There's a PyCode.
And what we're going to do here is we're going to create a new directory for IoT Push.
And we're going to do...
We're running out of time.
So thank you very much, everybody, for watching. I hope you really enjoy the rest of Cloudflare TV's programming for the day.