OctoPrint-TFT on a Raspberry Pi

octoprint-tft

So I have been seeing the new kid on the block pop up a lot recently, no not that shitty fucking band. This is a new “plugin” for the famous and awesome OctoPrint, OctoPi actually – OctoPrint-TFT. I have seen the screenshots and it is looking slick I must say. A while back I tried to use the OctoPrint TouchUI plugin and didn’t have much luck with it, in the end as the Pi I had at the time was a lower model and I just found the responsiveness just too slow. Plus this gives it a nice TFT feel like it was stock and meant to be. Le’s try it. I am gonna use the same waveshare 3.5″ LCD screen I had before but this time a newer Raspberry Pi 3B+. So I wont need a WiFi dongle this time either cause its built-in.

 

Parts used

  • Raspberry Pi 3 B+
  • Waveshare 3.5″ LCD TFT screen
  • A micro SD card of course
  • Power supply and cord for the Pi
  • USB cable to connect the Pi to the printer
  • A 3D printer lol
  • A computer with some sort of SSH program or a screen and keyboard/mouse to work directly off the Pi (might work I am not sure, I used a terminal on my mac and SSH’d into the Pi).

 

Let’s Party

Let’s follow the directions from the Github page and see what happens?

After installing a fresh copy of OctoPi v0.16 I started the Github directions.

 

The file is actually “/etc/octoprint-tft-environment” not the location.

sudo nano /etc/octoprint-tft-environment
(this tidbit copied form the github page)

The basic configuration is handled via environment variables, if you are using the  .deb package you can configure it at  /etc/octoprint-tft-environment.

  • OCTOPRINT_CONFIG_FILE – Location of the OctoPrint’s config.yaml file. If empty the file will be searched at the  pi home folder or the current user. Only used for locally installed OctoPrint servers.
  • OCTOPRINT_HOST – OctoPrint HTTP address, example  http://localhost:5000, if OctoPrint is locally installed will be read from the config file.
  • OCTOPRINT_APIKEY – OctoPrint-TFT expects an API key to be supplied. This API key can be either the globally configured one or a user specific one if “Access Control”. if OctoPrint is locally installed will be read from the config file.
  • OCTOPRINT_TFT_STYLE_PATH – Several themes are supported, and style configurations can be done through CSS. This variable defines the location of the application theme.
  • OCTOPRINT_TFT_RESOLUTION – Resolution of the application, should be configured to the resolution of your screen, for example  800x480. By default  480x320.

So go to the browser on your working machine that you use and go to the Pies IP address and go thru the OctoPrint setup fun. Once done grab an API key from the config menu on OctoPrint and lets edit that config file for the OctoPrint-TFT.

Do a find -name "config.yaml" on your Pi and you will find the location of yours. Add that to the config. Host should be http://localhost . The API you grabbed from the config menu slap that where it needs to go. I left the last two alone.

It has come a long way since the last time I tried to get this screen to work. This time its is really freaking easy!

This should install with the screen to boot with the bottom being the power plug, if you want it the other way do this instead

Reboot your Raspberry Pi and make sure you get video on your LCD.

If your screen is not rotated correctly with the above command still, do the following.

And change the line for your display to add :rotate=270 as shown below

The Pi rebooted after downloading some files and holy shit! The screen is working, well it showed the boot up sequence and a login prompt. Let’s get touch working and the desktop.

sudo reboot

Let’s see?

Boot up sequence and…login prompt. Ugh. sudo raspi-config to desktop? That loads and wants lightdm, so no. TFT wants xserver, so its gonna get xserver. Lets Google and I mead Reddit. Google didn’t have shit, too new still. Found it.

Let’s try this.

He has an extras step after installing OctoPrint-TFT.

Lastly we need to remove the 99-fbturbo.conf file from our Xorg directory he says.

Now on reboot OctoPrint-TFT should load and start attempting to connect says he?

Fucken eh right it did! If you see the Octoprint image but the error says

Unexpected error: Get /api/connection: unsupported protocol scheme

As mentioned earlier I found out on the Github issues page it was mentioned there to add “http://” to the config file instead of just localhost. So make sure you did that.

If you see the “Connecting to OctoPrint” and it never goes away, don’t wait too long! It simply means it has no connection to a 3D printer at that moment. You MUST plug it in for the TFT to do its job and actually work. Incredibly confusing I know. Hopefully they’ll fix that soon, and change the message soon.

After playing with it for a few minutes (no actual printing done) I find it pretty neat, and may possibly use it in the future if my LCD screen ever loses functionality for some reason. I could disable the control boxes screen lets say and enable more features in Marlin, after I did upgrade my firmware. But I am not too sure. Requiring the tethered connection to the Pi is a drawback for me, thats way more plugs sticking out of a screen than I would like. If I had the 7″ screen to hide the goop maybe, but this wasn’t designed for those. It was perfect size on the 480×320 I ave.

Or if I do some crazy new board installed over the Melzi and I don’t have a screen. I could use this. I wanted to try Klipper out and that loses the screen but I don’t think there is support for it just yet. I am not willing to try it out at this point in time.

But that was my trick to get OctoPrint-TFT to work on my Waveshare 3.5″ TFT screen and Raspberry Pi 3 B+. Hope it helps.

 

The perfect Raspberry Pi enclosure

The perfect Raspberry Pi enclosure

There are many and I mean many Raspberry Pi cases out there. Fucking tons. There are a few great ones and a lot of mediocre ones. I came across a pretty good one. It is a great case and not just because it looks cool. It’s actually function-able. The case is designed to fit a VESA monitor mount. So if you have a TV or monitor on a stand you could bolt this to the rear and bam!. The holes are also great for general purpose mounting. The case is designed slightly different than all the others out there. There is NO CUTOUT for the micro USB power plug. We don’t use it here. This case has room for a DC-DC buck converter. Available on Amazon, eBay and all over. Standard part.

We take a nice big fat power source like 12v DC 3A and knock it down to 5.1v DC for the Pi. Then we wire that output directly to the Pies GPIO pins for 5v and GND. This works great, a nice fat stable power source. And the bricks are far easier to get a hold of then a 3A 5v USB plug. I have tons of them lying around.

DC-DC Buck Converter

 

We take the barrel plug and solder in a diode to the source side of the DC-DC buck converter. We take the output and apply that to the power GPIO pins for 5v and GND. Then we take a LED and wire in a 330ohm resistor and connect that to GND and GPIO 14 (UART TXD). Heres the trick to get the GPIO pin to follow the Pies power up and power down cycle. So the LED will turn off when the Pi is safe to unplug.

Edit your /boot/config.txt file and add the following line:

enable_uart=1

Thats it, now the LED will light when powered on and it will shutoff when it is safe to unplug the Pi. If you wish to use a different pin other than 14 you can follow this guide over here.

The case

Heres the thingy for my modified version of the case. The original calls for brass inserts for the screws, which is awesome I just don’t use them. So I remixed the files to use standard M3 screws. No more brass inserts. I also increased the depth of the lid. My jumper wires were hitting the top of the  lid and preventing me from closing it. No I have plenty of room fire wires and jumpers.

My Remixed Case

https://www.thingiverse.com/thing:2956874

Original Version

https://www.thingiverse.com/thing:2286741

 

Retrieving my IP address Remotely

Retrieving my IP address Remotely

I posted a few years ago about using Twilio and Node-Red to send/receive SMS messages. Using that flow you gain the ability to text your server and have it read back values. Any values you want, as long as you have them stored as a global some where along the way. If you haven’t already done it toss $20 on an account at Twilio for a year and get to it, its so worth it! Here I am going to add a new reading to my setup.

There are occasions when I need to access my home network when I am, well, not home. Everyone screams use a VPN! Yeah, of course, I have one, and I use it. But my problem is I have a dynamic WAN IP and I am not paying for a static IP. It doesn’t change very often but it always seems to when I need to use it the most. Step in Node-Red and Twilio. With both of those at my disposal I can now send a text message to my home server and have it respond with my WAN IP address. I can then modify my VPN settings on my phone or whatever if needed. Fucking fantastic! I had been using Twilio/NR for sensor readings and alerts but I had never thought about using it to report my IP. Theres a few ways to do this.

Lets grab our IP (the flow)

(This flow grabs the WAN IP via an exec node)

First we use an inject node and set it to fire off once on start, this grabs the IP first thing and makes sure we have some data to work with. Then we move off to an execute node. We are gonna execute some command line code and echo it back, then we’ll save it in a file and as a global. This goes in the exec node:

wget -qO- http://bot.whatismyipaddress.com/ ; echo

This goes out to whatismyipaddress.com and echoes back our IP, simple and very fast. There are a few other sites that can be used also. Ifconfig.io and ipinfo.io both are alternative sites (you just have to change the truncation from 5 to 6 characters to drop the return sign in the following function node).

Alternatively, and preferably we can use an HTTP node instead of an exec node. What? Yeah I just found this out.

(This flow grabs the IP via an HTTP node)

That will get you your WAN IP quickly via an HTTP node formats it then saves it to a file. We have to comment out the substring trimming command if we use the HTTP node over the exec node. Ok no problem. Don’t forget.

After we grab the IP we need to format it and save it as a global for Twilio (and Alexa!).

This will trim the returned output from the website to 6 characters, dropping off anything extra. It also saves our trimmed value as a global. Then we slap on a debug node and a file node to save the IP to a file for later use. You don’t have to save the IP to a file, I just like to in the even the server is restarted/power loss.

Thats it! Once the IP has been picked up and set as a global you are good to go (as long as you followed the other flow for Twilio I posted previously).

 

It figures…

After typing this up and saving the draft I decided to update NPM/nodejs/Node-Red. Upon updating I came across a Node-Red node, node-red-contrib-ip.

A simple install via Palette Manager (which doesn’t work for me) or manually installed via npm install node-red-contrib-ip and you’re good. The node works simply, nothing to configure. Add an inject node to trigger it and it spits out your machines IPv4 and IPv6 address and well as your WAN IP address. Just have to format the data the way you want and boom. I did notice it is slow, painfully slow. It doesn’t need to be lightning quick but it is noticeable compared to the wget option above. Choose your weapon, either method works. Heres the flow for using the IP node.

(This flow grabs the WAN IP via the node red IP node)

After the IP node put a function node and fill it with this code

This drops all the other node info and just gives us the WAN IP. Easy as pie.

 

Lets get notified

So far we check our IP every 12hrs and write it to a file and a global for use. Thats great, we can take it one step further. Want to get a notification when the IP does change? Lets go.

(This flow grabs the IP via an HTTP node and checks if it has been updated, then sends a notification if it has)

  • Inject and repeat every 24hrs at a set time
  • Read the stored IP address by reading the file
  • Get the current IP address and set it as a global
  • Cross check to see if the new IP matches the old IP and save it to a file if it is newer.
  • Format the message payload and send a notification (however you like, pushbullet, email, Twilio etc)

 

Check out this site, its where I got the notifications from https://steve.zazeski.com/get-a-notification-when-your-wan-ip-changes/.

Custom Alexa Node-Red Skill (revisited)

alexa-nodered

Finally! I am surprised it didn’t even take as long as it usually does for me to figure shit out. Took a few weeks. As usual, I did not come up with the solution on my own but found it out on the web and slapped it all together. I wanted a custom Alexa Node-Red skill, to be able to take a command given to Alexa and have it read back data from one of my sensors. Things like temperature sensors, water level, etc. I wanted to be able to ask Alexa what the values are. What I got: exactly what I wanted. It all works. There is two parts to this: the Node-Red flow and the Alexa skill.

Alexa Node-Red flow
Alexa Node-Red flow

First off, to get any of this working you must have your Node-Red server accessible from the outside world. That means port-forwarding, DNS, domains, SSL, all that. It’s fun getting it all working. Not. Just like my previous post, I happened to have it already setup. Once your Node-Red install is available from the web you are good to go. Now you don’t need the entire NR setup opened up either. I just allowed a few NR served pages to be available. Not the entire NR itself.

Update: I made a new post about Node-Red behind a reverse-proxy/SSL

Let’s Begin

It starts with a regular HTTP node to a switch node. That switch node splits up Alexa’s requests to NR; LaunchRequest, IntentRequest, SessionEndedRequest. LaunchRequest gets invoked when the skill starts. You could have Alexa say “Hello what do you want?” for example. IntentRequest is the goods. Then theres SessionEndedRequest, I’m assuming this gets called at the end. Haven’t toyed with it. Then you pass those requests off to do other stuff, like the DoCommand where it grabs your intent. Then a function node to extract the commands, which gets passed off to another switch node to split up the possible commands you can give Alexa. Give her as many commands as you want, then there is a “device doesn’t exist” at the bottom. This is used if she didn’t hear you right or the device doesn’t exist. All that data gets passed to a template to format what Alexa will say and sticks the data in JSON. Bam! That wasn’t so hard right?

Here’s the whole flow (all standard nodes used):

That’s the Node-Red half. You are not done yet. On to the Alexa skills half. This part is easy don’t worry. Login to your Amazon Dashboard and click Alexa. Choose “Get Started” with the Alexa Skills Kit, click add a new skill. Under Skill Information give it a name and choose the invocation word, what you will say to Alexa to start your skill. I chose “Node Red”, so I have to say “Alexa, ask Node Red….”. These can be changed at any time it seems. You won’t be publishing this skill, it stays beta for only you to use. For the Global Fields section, no you will not be using an audio player. Well, maybe you will but I didn’t, and it will probably change things for you.

Note about the flow: The NR flow works (for me) just fine however I noticed it throws an error in the debug tab whenever a command is called. If it is an unrecognized command response it doesn’t throw the error though. It complains about headers already being sent. I will update the flow if I find a fix for it.

Interaction Model

Intent Schema

Intent Schema

This is the part of the Alexa skill where you tell it what to do. It is pretty straight forward. Just copy this to your “Intent Schema”. There are no custom slot types and no values to enter.

Sample Utterances

Sample Utterances

This is where you list the invocation phrases that will activate Alexa. Normally (and in other online tutorials for Alexa skills) this is where you add a ton of different phrases. But we are not. Node-Red is going to handle that side for us. This box just gets one line of text.

Configuration

Global Fields/Endpoint

For a service endpoint you are going to pick “HTTPS”. In a lot of other tutorials you will usually choose AWS Lambda but we are doing all of our own heavy lifting with NR. We don’t need no stinking Lambda. Choose your closest location and enter the URL that your Node-Red is accessible from (via the web remember). Say no to account linking and you can also leave Permissions alone.

SSL Certificate

Certificate for Endpoint

Choose the option that bests describes you. Most likely it will be the first option. For me I am using a subdomain that is already SSL’d with Let’s Encrypt so I choose the second option.

Test

Basically just leave the toggle flipped to enable the skill for you to use. you don’t need to do anything else on this page.

Publishing Information

Nothing to do here, you won’t be publishing this skill. Why? Because it requires too much setup on the users behalf. I don’t think Amazon would approve a half functioning skill that requires advanced user setup to get working. You could always try. Good luck.

Privacy & Compliance

Three no’s and one box to check, I mean as long as it all applies to you right 😉

Done

That should be it. With Node-Red available to the web and the flow implemented the new Alexa skill you just made you should be good to go. I hope you found this useful, I sure wish I had found a blog post like this. Now go test it out with your Amazon Echo/Dot!

At the time of this writing a beta product appeared in the Amazon Dashboard for a the “Skill Builder”, looks to be a new UI for building Alexa skills. If this gets implemented for everyone in the future things may be different than they are described in this blog post.

 

Revisited

Originally posted April 26, 2017 @ 17:56

I decided to come back to this post. I was adding and modifying some things on my flow and I was using this post as a reference and decided it was not cutting the mustard, it felt unfinished. So here we are.

The above section contains the main flow you will need and it steps you through the Amazon Developer side of things that needs to be setup. Once that is all finished you should have a working flow with Alexa responding accordingly. What I feel I left out was how to configure the flow itself. Many of you may already have figured it out or can see whats going on and thats cool. Heres for the ones that need the help (myself included).

The flow

Voice requests
Request (your questions)
Question function
Question function (global request)
Alexas response
Alexas verbal response

HTTP node

The first node in the flow is the HTTP request. This is the page you will use to point your reverse proxy to. This is the page that Node-Red will server, that Amazon/Alexa will look for. This page needs to be accessible from outside your network.

Request Type

This contains the types of requests we can send to Alexa. We are only worried about IntentRequest  right now. Play with the other later.

Intents & Extract Commands

There is no need to modify these nodes. They contain the code needed to send requests.

Request

Add your verbal question here. Add it how Alexa hears it. This may take a little trial and error depending on how you talk and how she hears you. Sometimes you can simply put exactly what you are going to say in there, like “garage temperature” works fine for me but if I ask Alexa what the outside temperature is she doesn’t know and I get the unrecognized question response. But this is ok, pay attention to the output of the unrecognized responses. It will spit out what Alexa heard and how she heard it. So when I ask what the outside temperature is she hears “i outside temperature” for some unknown reason. So if I modify my request to be the same, and it works.

Function node

This function is very simple. It just grabs the global variable name you put in it. So when I ask for the “garage temperature” it looks for the global I have specified, in this case contex.global.garagetemperature. Add whatever global you want. Just make sure it is initialized first (has some data to report).

Formatting Alexas response

This template node contains the information for Alexas verbal reply. Once the basic structure is there all you do is edit the “text” to the response you want to receive, in plain english. She will respond with “exactly” what you type in there.

JSON & HTTP Response

Move along, noting to see here. The data gets formatted as JSON and the HTTP node completes the whole flow.

Done.

 

There you go. I feel better now. I at least explained WTF is going on here rather than dumping the flow on you and walking away. Sorry about that. Now you can run off and play with Alexa and Node-Red to your hearts content. The only thing I have noticed with the whole flow is that after Alexa responds Node-Red throws an error in the debug log. It all works 100% and works well but it always sends this error, and I haven’t figured it out. But I also haven’t been looking for it. Just a little FYI.

"Error: Can't set headers after they are sent."

 

This is where I found the goodness, buried deep in comments on a (awesome) blog.