Software apps and online services

Hand tools and fabrication machines

3D Printer (generic)

Story

Intro and Overview

When I start a 3D print I don’t sit around waiting for it to finish so I can start another one, I get up and do something more productive. This though, can sometimes lead to problems like me forgetting whether or not my printer is currently printing or wondering how much time it will be until I can start another print. The desire to be able to remotely monitor my print led me to OctoPrint, a program which when loaded onto a raspberry pi and connected to a 3D printer lets the printer be controlled and monitored from a website. Though this helped, I wasn't a fan of having to pull out my phone every time I was curious of my 3D printer's state. So, I made it even easier for myself to check on my printer by creating what I call 3D Printer Host.

3D Printer Host is a do it yourself electronic device created with a WiFi enabled Adafruit Feather, a Neopixel ring, and a 3D printed enclosure. The device connects to OctoPrint via its API and the wonderful OctoPrint API library for Arduino. It displays the print’s progress as well as state on the Neopixel ring. The 3D Printer Host also connects to Alexa via Thingspeak and a custom skill which allows a user to ask Alexa about many aspects of their printer and find details about any current print. Though the way in which this device functions may be confusing, it is all easily explained in the following diagram.

Flowchart of data through the Printer Host device and external programs

A demo of the 3D Printer Host can be found below. I have created and published an Alexa skill called 3D Printer host to the Alexa skill store. This skill showcases the functionality of building a 3D Printer host skill for yourself. This published skill will not alow users to monitor their own printer. To do so, this tutorial should be followed to create a Printer host of your own.

A demonstration of Printer host’s functionality

Just a note before we start: all code, models, and other files can be found at the bottom of this page.

Hardware

To begin, gather the electronic components along with some wire. There are three options for printing the enclosure. First, you can print the 'Base', 'Outer Cover', and 'Inner Cover' in a color of your choice and print the 'Cover Slip' out of a transparent filament. The three cover parts will snap together causing the Neopixel ring to shine directly through the transparent filament. Second, the 'Base', 'Outer Cover', and 'Inner Cover' can be printed out of a color of your choice allowing the raw Neopixels to be seen. The third option is to print the 'Full Cover' along with the 'Base' in a lighter color filament and let the light shine through the single color of the cover. All files are linked to at the bottom of this page.

1 / 6 • 1st option off

Start by soldering the DC power on the Neopixel to the 3v pin on the Feather. Solder ground to ground and data input to pin 12. The circuit diagram shows the correct wiring.

Correct wiring

Place the Feather on the standoffs as pictured below.

Make sure the USB port is facing its cutout

Snap the Neopixel ring into its channel.

The Neopixel ring should snap firmly into place

Finally, screw on the cover of your choice.

I went with the first design option

OctoPrint API Setup

For this entire system to begin to work the first thing you must do is hook up you printer to OctoPrint. To do this you will need

A Raspberry pi microcomputer

Accessories such as power supply and case

An SD card with latest OctoPrint image

For a full instruction guide on installing OctoPrint go to the OctoPrint website. Any further Information or clarification can be found on Youtube or other online guides.

Once OctoPrint is up and running, go to your OctoPrint server (typically https://Octopi.local), login, and head to the API Settings. Enable the API and allow CORS. Finally, take note of the API Key because this will need to be pasted into code later.

The API Key is used to relay data from your printer to the 3D Printer Host Arduino

Thingspeak Configuration

Thingspeak will be used to store data coming from OctoPrint via the Arduino into an http requestable channel. This will allow the Amazon Lambda function to request and receive data from the Thingspeak channel and relay the data through Alexa to the user.

First, create a Thingspeak profile by following the link here. Verify your account by clicking the link they sent you via email. Finally Navigate to the 'Channels' page header and click 'New Channel'.

For this project we will be creating two channels, one for the printer data and another for the print job. Once you have navigated to the channel setup page make it look like the picture below.

Copy into Thingspeak Channel

Once your channel matches as shown above you may click the 'save channel' button at the bottom. Next navigate back to 'My Channels' and create another channel. Fill in the information as shown again to set up the print job monitoring channel. Save the channel when completed.

Copy into Thingspeak Channel

Create one more channel following the outline below:

Copy into yet another thingspeak channel

Once complete, head over to the 'API Keys' tab of each channel. Here you will find your Write API Key and Read API Key for that channel. Both of these will become important later so make sure you know how to get to them.

This Information is channel specific so should be found for both channels

Arduino Code

Most of the Printer Host's functionality is found in the esp8266 equipped Arduino board which connects together OctoPrint, the Neopixels, and Alexa (Thingspeak).

First of all, you must have an Updated version of the Arduino IDE which can be found here. Next, copy the 'Arduino Code' found at the bottom of this page into a new Arduino sketch.

The code needs a few libraries and drivers to allow it to function properly. The Adafruit Feather Drivers which allow the Feather to be recognized and programmed with a computer can be downloaded here. Next, the esp8266 library for Arduino must be downloaded, paste

http://arduino.esp8266.com/stable/package_esp8266com_index.json

into the additional boards menu under file ==> preferences. Additional boards can be separated with commas.

After that, go to Tools ==> Board and select the Adafruit HUZZAH ESP8266. Plug in your Printer Host Gadget and select the correct COM port, make sure that under Tools, you have self selected the following settings.

Frequency: 80MHz

Flash Size: 4M(3M SPIFFS)

Upload Speed 115200

Finally, fill in your wifi credentials, Octoprint API key, OctoPrint IP address and Thingspeak write API keys for both channels under the 'User Data' section of the Arduino Code. Make sure to keep the quotation marks and remove all of the dashes.

Quotation marks must not be deleted, no spaces before or after each input

Color Settings can be changed to customize the color scheme of your Printer Host, but have not been tested and could cause errors.

Upload the sketch by hitting the forward arrow at the top of the screen.

Amazon Skill

Alexa Skills are based out of and configured by the Alexa Skills Kit on the Amazon Developer Console. Start by following this link and create a new account using the email that you have connected to your Alexa. Next, go to the developer console , and then to the 'Alexa Skills Kit' tab. From here click Create Skill. As prompted create a name for the skill ex: '3D Printer Host', and choose the skill type as custom. Finally click 'Create Skill'.

You will now be transported to the 'build' page of your skill. Navigate to the JSON editor using the menu on the left side.

Replace the code from in the JSON editor with the Interaction Model code linked to at the bottom of this page. Click the 'save model' and then 'build model' buttons at the top of the screen. If you want to change the invocation name (what is said to trigger the skill) to something besides 'printer host' simply replace it with the desired value at the top of the code.

For example "Alexa, ask <invocation name> how long my print has left?"

To continue, a Lambda function must be constructed and configured via AWS (Amazon Web Services). This function will interprate the request that the Alexa skills kit sends it. The function will respond with an Alexa speech string that Alexa will say. To start the process follow this link and create an account. You will need to hook up credit card information, but since the free tier suits all of this projects needs nothing will be charged. Verify the account by following the directions onscreen, select the free plan, and then sign into the console. Make sure that your selected region in the top right corner is N. Virginia no matter where you live.

Search and select Lambda from the AWS services search. Click 'Create function', 'Author from scratch', and fill in the details to match the ones below. Then create the function.

Lambda Function Details

Once the function has been created, find the Designer section which consists of a flowchart. Add the 'Alexa Skills Kit' trigger from the list on the left. It will ask for the skill ID, so paste the skill ID that was copied earlier here. Navigate to the function code by clicking on the Printer Host section of the flowchart and scrolling down. Paste the Index Lambda code into the index.js file. In the Index.js file locate the 'User Input' section and fill in the IDs, write, and read keys of all Thingspeak channels and the Application Id of the of the Alexa skill created earlier. After that, create a new file and name it 'AlexaSkill'. Copy the Alexa Skill Lambda Code into the new file. Once all of that is complete, the Lambda function should be saved.

Copy the ARN (Amazon Resource Name) in the top corner of this Lambda function and proceed back to the Alexa skill created earlier in the Amazon Developer Console. Go to the Endpoint page and paste the ARN that was just copied into the Default slot. Be sure to save the endpoints . The Configuration page should like like the following.

Alexa Skill endpoint configuration

Now proceed to the Test page and under the 'Alexa Simulator' enter the utterance 'alexa, ask printer host how my printer is doing'. The response should include a statement about the state of your printer and its temperatures. If you do not get this response, go back and review the setup of Thingspeak, Lambda, and the Alexa skill. If the response did come back as hoped, congratulations your 3D Printer Host is up and running.

Use

To activate your Alexa skill go to the Alexa app on your phone and navigate to Skills==> Your Skills ==> Dev Skills. Click on the Printer Host skill and enable it. You can now monitor your 3D printer via Alexa.

Monitoring

The 3D Printer Host Alexa Skill can answer many requests relating to both the printer and print job. All of these functions can be triggered by many ways of wording each request.

Asking about the printer: 'How is my printer?' will respond with whether or not the 3d printer is operational and what it is currently doing. (printing, paused, or standing by)

Asking for an overview: 'Give me an overview.' will respond with an overview of the current print job. Ex: 'Your printer has 2 hours and 45 minutes left on a 6 hour and 10 minute print of 3D_Benchy.gcode'

Asking 3D printer host what it can do: 'What are you capable of?' will return a list of available commands.

Asking for the amount of time remaining:'How much time is left on my 3d print?' will respond with the amount of time in hours and minutes remaining on the printer current print job.

Asking about the total estimated time:'How much time is my print expected to take?' will return the time in hours and minutes that the printer's current print is expected to take .

Asking about the time printed:'How long has my printer been printing?' will return the amount of time that the printer has been printing the current print.

Asking about the percentage completed: 'What percent of my print has been completed?' will return the relative percentage of the current print that has been completed.

Asking for the file name: 'what is the name of the file that is currently being printed?' will trigger a response which includes the name of the file currently being printed.

VUI

Controlling

Users of this device are now able to control their 3D printers via Alexa and the 3D Printer Host Gadget using post commands.

The following commands are supported:

Canceling: Asking printer host to cancel the current print.

Restarting: Ask printer host to restart a print or file.

Pausing: Ask printer host to pause print.

Start: Ask printer host to start print. Starts a print of whatever file is currently selected.

Reading the Gadget

The Printer Host's ring of Neopixels can communicate many aspects of the printer and current print. These colors are set by default but can be changed in the Color Settings section of the Arduino code.

A full circle of red light means that the printer or OctoPrint is disconnected or experiencing an error. Check that the Raspberry pi that is hosting OctoPrint is connected to power and the 3D printer.

A full circle of blue light or no light (depending on whether or not background is turned on in the Arduino code) indicates that the printer is standing by. The 3d printer is connected and ready to print but is not currently printing.

A partial circle of green means that a print is currently in progress. The progress of the print is displayed by the percentage of the Neopixel Ring filled. If the print is 20% completed, the ring will be roughly 20% full. If 100% of the ring is full it doesnt mean that your print is done, just that

A partial circle of yellow indicates that the print is paused. The progress of the print is displayed as the percentage of the Neopixel Ring filled.

Future

This entire system is made possible by the OctoPrint API library for Arduino. This library is relatively new (January 2018) and as so does not yet support all the functionality of OctoPrint's API. As the library is updated I will update this project to allow for new functionality. Other exciting features are coming soon so stay tuned for ways to update your 3D Printer Host.

Custom parts and enclosures

Enclosure

Schematics

Circuit Diagram

Code

Amazon Sample Utterances

ColdFusion

Paste into amazon sample utterances box.

Introduction to introduce itself
Introduction introduce yourself
Introduction introduction
Introduction what can you doIntroduction what are you capable of
Introduction what it is capable of
Introduction what is can doIntroduction what it's functions areIntroduction about its functionalityIntroduction what is is that you can doIntroduction what exactly can you doIntroduction what is your prposeIntroduction who are youIntroduction what is the purpose of youIntroduction what is printerhostIntroduction what do it does with my printerIntroduction what it does with my three dee printerIntroduction how and what ist is capable of doing with my three dee printerIntroduction what were you designed to doIntroduction what problem do you solveOverview overviewOverview give me an overviewOverview to overviewOverview please overviewOverview to please give me an overviewOverview to summarise my printOverview to get me an overview of my printOverview to give a summary of my printOverview to tell me how my print is doingOverview to tell me a summary of my printOverview how is my printOverview how is my print goingOverview what is happening with my printOverview what is going on with my printOverview how is myy three dee printOverview how's my three dee print doing
Overview to check on my print
Overview to check on my three dee print
Overview to give me a summary of my print
Overview to give me a summary of my three dee print
TimeLeft how much time is left on my print
TimeLeft how much time is left on my three dee print
TimeLeft how much longer will it be until my print is doneTimeLeft how much longer will it be until my three dee print is doneTimeLeft how much more time is left on my print
TimeLeft how much more time is left on the print
TimeLeft how much more time is left on my three dee print
TimeLeft how much more time is left on the three dee print
TimeLeft how much longer does my printer have to go
TimeLeft how much longer does my printer have left
TimeLeft how much timeuntil completion
TimeLeft when will my print be doneTimeLeft when will my print completeTimeLeft when will my print be finished
TimeLeft when will the print be finished
TimeLeft time left
TimeLeft how much more timeTimeLeft time remaining
TimeLeft to tell me how much time is left
TimeLeft to tell my how much time is left opn my print
TimePrinted how long has my printer been printing forTimePrinted how long has my three dee printer been printing forTimePrinted how much time has my three dee printer been prining forTimePrinted how many hours have been printed
TimePrinted time printed
TimePrinted how long has my print been going forTimePrinted how long has my print been printing
TimePrinted how long has my three dee print been three dee printing
TimePrinted to tell me how long my printer has been printing
TimePrinted to tell me how much time my three dee print has been printing forTimePrinted how long my printer has been running
TimePrinted how long my print has been three dee printing
TimePrinted for how much time my printer has printed
TimePrinted for how long my printer has been printing
TimePrinted for how long my printer has been printing forTimePrinted for the time that I have been printing
TimePrinted for the time that my print has been printing forTimePrinted for the amount of time that my printer has already priunted
TimePrinted the amount of timefor which my three dee printer has been three dee printing
TimePrinted the time my printer has spent printing
PercentComplete what percent of my print is completed
PercentComplete percent completed
PercentComplete what percent of my print has been printed
PercentComplete to what extent has my print finished
PercentComplete what percent is my print donePercentComplete how much of my print has been printed
PercentComplete what percent is my print completed
PercentComplete to tell me what ercent of my print is finished
PercentComplete to tell me what percentage my print is completed
PercentComplete what percent of my print is donePercentComplete how far my print is in percentage
PercentComplete for the percentage my print has completed
PercentComplete for the percentage of which my print has printed
PercentComplete the percentage of my print which has been printed
PercentComplete the amount that my print is finished in percent
PercentComplete how much percent my printer is donePercentComplete the percent completion of my print
PercentComplete the percent which my printer has completed
PercentComplete how much print is done in percent
PercentComplete the percentage of three dee print completion
PercentComplete the percentage my three dee print has printed
PercentComplete how many percents my printer has printed
EstimatedTime how long is my print expected to take
EstimatedTime how long should this print take
EstimatedTime how long should it take my printer to print this model
EstimatedTime how much time will it take for my printer to print this
EstimatedTime what is the estimated print time of my print
EstimatedTime what's the expected print time of my printEstimatedTime what amount of time is necessary for my print to fully completeEstimatedTime how much time will my print takeEstimatedTime how much time will ti take my print to fully printEstimatedTime how long my print is expected to lastEstimatedTime how much time my print is estimated to lastEstimatedTime the amount of time my three dee print will takeEstimatedTime how long it will take my three dee print to print from start to finishEstimatedTime estimated timeEstimatedTime total estimated print timeEstimatedTime expected print timeEstimatedTime for the expected print timeEstimatedTime for the ammount of time my print should takeEstimatedTime for the time my print will takeEstimatedTime for the time my three dee printer will take to completeFileName file nameFileName what file do I have selectedFileName which file I have selectedFileName which file I am printingFileName what file I am printingFileName for the name of the file I have selectedFileName for the name of the file I have chosenFileName for the name of the file that is printingFileName what is printingFileName what my three dee printer is printingFileName what file my three dee printer is three dee printingFileName the file nameFileName to tell me the name of the file I have selectedFileName to tell me which file I am printingFileName to tell my what file I my printer is currecntly printingFileName what file is quedFileName for the file nameFileName to tell me te file nameFileName what S T L my printer is printingFileName which g code is my printer printingFileName what is my printer printing currentlyPrinterData printer dataPrinterData how is my printerPrinterData how is my printer doingPrinterData what is going on with my printerPrinterData how well is my printer doingPrinterData statusPrinterData operationPrinterData is my printer printingPrinterData is my printer pausedPrinterData is my printer connectedPrinterData printerPrinterData if my printer is brokenPrinterData if my three dee printer is functioningPrinterData if my printer is functiningPrinterData to tell me the status of my printerPrinterData about my printerPrinterData about my three dee printerPrinterData if my printer is running smoothlyPrinterData to tell me how my printer is doingPrinterData how is my printerPrinterData how's my printer

Interaction Model

JSON

Paste into JSON box of the Amazon Skill service

{"interactionModel":{"languageModel":{"invocationName":"printer host","intents":[{"name":"AMAZON.CancelIntent","samples":[]},{"name":"AMAZON.HelpIntent","samples":[]},{"name":"AMAZON.StopIntent","samples":[]},{"name":"EstimatedTime","slots":[],"samples":["how long is my print expected to take","how long should this print take","how long should it take my printer to print this model","how much time will it take for my printer to print this","what is the estimated print time of my print","what's the expected print time of my print","what amount of time is necessary for my print to fully complete","how much time will my print take","how much time will ti take my print to fully print","how long my print is expected to last","how much time my print is estimated to last","the amount of time my three dee print will take","how long it will take my three dee print to print from start to finish","estimated time","total estimated print time","expected print time","for the expected print time","for the ammount of time my print should take","for the time my print will take","for the time my three dee printer will take to complete"]},{"name":"FileName","slots":[],"samples":["file name","what file do I have selected","which file I have selected","which file I am printing","what file I am printing","for the name of the file I have selected","for the name of the file I have chosen","for the name of the file that is printing","what is printing","what my three dee printer is printing","what file my three dee printer is three dee printing","the file name","to tell me the name of the file I have selected","to tell me which file I am printing","to tell my what file I my printer is currecntly printing","what file is qued","for the file name","to tell me te file name","what S T L my printer is printing","which g code is my printer printing","what is my printer printing currently"]},{"name":"Overview","slots":[],"samples":["overview","give me an overview","to overview","please overview","to please give me an overview","to summarise my print","to get me an overview of my print","to give a summary of my print","to tell me how my print is doing","to tell me a summary of my print","how is my print","how is my print going","what is happening with my print","what is going on with my print","how is myy three dee print","how's my three dee print doing","to check on my print","to check on my three dee print","to give me a summary of my print","to give me a summary of my three dee print"]},{"name":"PercentComplete","slots":[],"samples":["what percent of my print is completed","percent completed","what percent of my print has been printed","to what extent has my print finished","what percent is my print done","how much of my print has been printed","what percent is my print completed","to tell me what ercent of my print is finished","to tell me what percentage my print is completed","what percent of my print is done","how far my print is in percentage","for the percentage my print has completed","for the percentage of which my print has printed","the percentage of my print which has been printed","the amount that my print is finished in percent","how much percent my printer is done","the percent completion of my print","the percent which my printer has completed","how much print is done in percent","the percentage of three dee print completion","the percentage my three dee print has printed","how many percents my printer has printed"]},{"name":"PrinterData","slots":[],"samples":["printer data","how is my printer","how is my printer doing","what is going on with my printer","how well is my printer doing","status","operation","is my printer printing","is my printer paused","is my printer connected","printer","if my printer is broken","if my three dee printer is functioning","if my printer is functining","to tell me the status of my printer","about my printer","about my three dee printer","if my printer is running smoothly","to tell me how my printer is doing","how's my printer"]},{"name":"StartPOST","slots":[],"samples":["start my print","start a print of the current selected file","commence printing","begin a print","begin my print","start print","start printing","start the print","start printing selected file","start printing the file i selected","start printing the currently selected file"]},{"name":"TimeLeft","slots":[],"samples":["how much time is left on my print","how much time is left on my three dee print","how much longer will it be until my print is done","how much longer will it be until my three dee print is done","how much more time is left on my print","how much more time is left on the print","how much more time is left on my three dee print","how much more time is left on the three dee print","how much longer does my printer have to go","how much longer does my printer have left","how much time until completion","when will my print be done","when will my print complete","when will my print be finished","when will the print be finished","time left","how much more time","time remaining","to tell me how much time is left","to tell my how much time is left opn my print"]},{"name":"TimePrinted","slots":[],"samples":["how long has my printer been printing for","how long has my three dee printer been printing for","how much time has my three dee printer been prining for","how many hours have been printed","time printed","how long has my print been going for","how long has my print been printing","how long has my three dee print been three dee printing","to tell me how long my printer has been printing","to tell me how much time my three dee print has been printing for","how long my printer has been running","how long my print has been three dee printing","for how much time my printer has printed","for how long my printer has been printing","for how long my printer has been printing for","for the time that I have been printing","for the time that my print has been printing for","for the amount of time that my printer has already priunted","the amount of time for which my three dee printer has been three dee printing","the time my printer has spent printing"]},{"name":"CancelPOST","slots":[],"samples":["end the current print","cancel the file currently printing","cancel the file i am printing","cancel the print that is printing","cancel the print that is being printed","cancel my current print","end my print","cancel","cancel my print"]},{"name":"RestartPOST","slots":[],"samples":["restart the file printing","restart my three dee print","restart the three dee print","restart the print that is currently printing","restart","restart the file my three dee printer is printing","restart my current three dee print","restart the current print","restart my print"]},{"name":"PausePOST","slots":[],"samples":["pause the three dee print","resume the three dee print","resume the file being printed","unpause the print my pinter is printing","pause the print","pause the current file","resume the current model","unpause my print","unpause","resume print","resume printing","resume","pause","pause my print"]},{"name":"ConfirmPause","slots":[],"samples":["confirm the resume","confirm resume","please pause","yes pause","confirm pause"]},{"name":"ConfirmStart","slots":[],"samples":["start confirm","yes start","confirm the start","confirm start"]},{"name":"ConfirmRestart","slots":[],"samples":["confirm the restart","restart confirm","restart confirmed","confirm restart"]},{"name":"ConfirmCancel","slots":[],"samples":["confirmed cancel","cancel confirmed","confirm the cancel","confirm cancel"]},{"name":"CommandPOST","slots":[],"samples":["have the printer do a command","send a custom command","excecute a custom command"]},{"name":"ConfirmCommand","slots":[],"samples":["command confirmed","confirm command"]}],"types":[]}}}

Arduino Code

C/C++

Paste into a new Arduino Sketch

/*Printer Host 1.0.0This sketch will receive data from octoprint, write it to thingspeak channels, and display the data on a neopixel ring. */#include<ThingSpeak.h>#include<ESP8266HTTPClient.h>#include<ESP8266WiFi.h>#include<String.h>#include<OctoPrintAPI.h>#include<Adafruit_NeoPixel.h>#include<WiFiClient.h>#include<ArduinoJson.h>unsignedlongapi_mtbs=60000;//mean time between api requestsunsignedlongapi_lasttime=0;//last time api request has been doneunsignedlongapi2_mtbs=60000;//mean time between api requestsunsignedlongapi2_lasttime=0;//last time api request has been done#define ringLength 16#define PIN 12Adafruit_NeoPixelstrip=Adafruit_NeoPixel(60,PIN,NEO_GRB+NEO_KHZ800);uint32_toff=strip.Color(0,0,0);WiFiClientclient;//------------------------------------------// User Data//------------------------------------------constchar*ssid="----------";//your SSID(name) of WIFIconstchar*password="----------";// password of WifiStringOctoPrintAPIKey="----------------";//API key from OctoPrintunsignedlongprinterID=------;//channel id of thingspeak printer channelconstchar*printerWriteApiKey="----------------";//write api key for thingspeak printer channelunsignedlongjobID=------;//channel id of thingspeak job channelconstchar*jobWriteApiKey="----------------";//write api key for thingspeak job channelStringPOSTWriteApiKey="----------------";//write api key for thingspeak POST channelStringPOSTReadApiKey="----------------";//read api key for thingspeak POST channelStringPOSTid="------";//channel id for thingspeak POST channelIPAddressip(--,-,-,---);// IP adress of Raspberry Pi. 11.1.1.111 = (11, 1, 1, 111)constintoctoprint_httpPort=80;//If you are connecting through a router this will work, but you need a random port forwarded to the OctoPrint server from your router. Enter that port here if you are external//------------------------------------------// Color Setttings//------------------------------------------intbackground=1;//Would you like yout Printer Host to show a color even when not printing? 1 = yes 0 = nointbrightness=150;//How bright would you like your Neopixel Display? 1-255uint32_tstandby=strip.Color(0,0,255);//What color would you like to show as the background (disregard if you do not want a background)uint32_terror=strip.Color(255,0,0);//What color would you like to indicate that the printer is disconnected or experiencing an erroruint32_tpaused=strip.Color(255,255,0);//What color would you like to indicate that the printer is pauseduint32_tprinting=strip.Color(0,255,0);//What color would you like to indicate that the printer is printing//All Colors Are In RGB Format//------------------------------------------//------------------------------------------StringpostStart;StringpostCancel;StringpostRestart;StringpostPause;booldebug=true;StringTSPostString;intbedTemp;inttoolTemp;Stringoperational;Stringstatus;StringfileName;StringpercentComplete;intpercent;inttimePrinted;inttimePrintedRemaining;StringtimePrintedHours;StringtimePrintedMinutes;inttimeLeft;inttimeLeftRemaining;StringtimeLeftHours;StringtimeLeftMinutes;intestimatedTime;intestimatedTimeRemainder;StringestimatedTimeHours;StringestimatedTimeMinutes;constchar*ESP_HOST_NAME="esp-"+ESP.getFlashChipId();constchar*host="api.thingspeak.com";//WiFiClient client; OctoprintApiapi(client,ip,octoprint_httpPort,OctoPrintAPIKey);voidwifiConnect(){WiFi.begin(ssid,password);Serial.print("ssid");while(WiFi.status()!=WL_CONNECTED){delay(500);Serial.print(".");}Serial.println("");Serial.println("WiFi connected!");Serial.println(WiFi.localIP());Serial.println();}voidsetup(){Serial.begin(115200);delay(10);strip.begin();strip.show();// Initialize all pixels to 'off' strip.setBrightness(brightness);// start by connecting to WiFi wifiConnect();ThingSpeak.begin(client);//Reset POST commandsclient.print(String("GET ")+"/update?api_key="+POSTWriteApiKey+"&field1=0&field2=0&field3=0&field4=0 HTTP/1.1\r\n"+"Host: "+host+"\r\n"+"Connection: close\r\n\r\n");}voidloop(){delay(100);//-----------------------------------------------------------------------------// Fetch data from Octoprint//-----------------------------------------------------------------------------if(millis()-api_lasttime>api_mtbs||api_lasttime==0){//only do this after a certain period of time has passedif(WiFi.status()==WL_CONNECTED){//Check WiFi connection status if(api.getOctoprintVersion()){Serial.println("---------Version---------");Serial.print("Octoprint API: ");Serial.println(api.octoprintVer.octoprintApi);Serial.print("Octoprint Server: ");Serial.println(api.octoprintVer.octoprintServer);Serial.println("------------------------");}Serial.println();if(api.getPrinterStatistics()){Serial.println("---------Stats---------");Serial.print("Printer Current State: ");Serial.println(api.printerStats.printerState);Serial.print("Printer State - closedOrError: ");Serial.println(api.printerStats.printerStateclosedOrError);Serial.print("Printer State - error: ");Serial.println(api.printerStats.printerStateerror);Serial.print("Printer State - operational: ");Serial.println(api.printerStats.printerStateoperational);Serial.print("Printer State - paused: ");Serial.println(api.printerStats.printerStatepaused);Serial.print("Printer State - printing: ");Serial.println(api.printerStats.printerStatePrinting);Serial.print("Printer State - ready: ");Serial.println(api.printerStats.printerStateready);Serial.print("Printer State - sdReady: ");Serial.println(api.printerStats.printerStatesdReady);Serial.println();Serial.println("------Termperatures-----");Serial.print("Printer Temp - Tool (°C): ");Serial.println(api.printerStats.printerTool0TempActual);Serial.print("Printer State - Bed (°C): ");Serial.println(api.printerStats.printerBedTempActual);Serial.println("------------------------");}Serial.println();if(api.getPrintJob()){//Get the print job API endpointSerial.println("---------------------------");Serial.print("Printer current state string:\t");Serial.println(api.printJob.printerState);Serial.println();Serial.println("----------Job (File information)--------");Serial.print("jobFileDate (Epoch) long:\t");Serial.println(api.printJob.jobFileDate);Serial.print("jobFileName String:\t\t");Serial.println(api.printJob.jobFileName);Serial.print("jobFileOrigin String:\t\t");Serial.println(api.printJob.jobFileOrigin);Serial.print("jobFileSize (bytes) long:\t");Serial.println(api.printJob.jobFileSize);Serial.print("estimatedPrintTime (sec) long:\t");Serial.println(api.printJob.estimatedPrintTime);Serial.println("----------------------------------------");Serial.println();Serial.println("-------Job (Progress information)-------");Serial.print("progressCompletion (%) float:\t\t");Serial.println(api.printJob.progressCompletion);Serial.print("progressFilepos (bytes) long:\t\t");Serial.println(api.printJob.progressFilepos);Serial.print("progressPrintTime (sec) long:\t\t");Serial.println(api.printJob.progressPrintTime);Serial.print("progressPrintTimeLeft (sec) long:\t");Serial.println(api.printJob.progressPrintTimeLeft);Serial.println("----------------------------------------");Serial.println();}//Map Values to Variablesoperational=api.printerStats.printerStateoperational;if(api.printerStats.printerStatePrinting==1){status="1";//if printing, set status to printing}elseif(api.printerStats.printerStatepaused==1){status="2";}elseif(api.printerStats.printerStateready==1){status="3";}else{status="4";}//map all received data to variables and convert times to hh:mm formattoolTemp=(api.printerStats.printerTool0TempActual);bedTemp=(api.printerStats.printerBedTempActual);fileName=api.printJob.jobFileName;estimatedTime=api.printJob.estimatedPrintTime;percentComplete=api.printJob.progressCompletion;percent=percentComplete.toFloat();timePrinted=api.printJob.progressPrintTime;timeLeft=api.printJob.progressPrintTimeLeft;timePrintedHours=timePrinted/3600;timePrintedRemaining=timePrinted%3600;timePrintedMinutes=timePrintedRemaining/60;timeLeftHours=timeLeft/3600;timeLeftRemaining=timeLeft%3600;timeLeftMinutes=timeLeftRemaining/60;estimatedTimeHours=estimatedTime/3600;estimatedTimeRemainder=estimatedTime%3600;estimatedTimeMinutes=estimatedTimeRemainder/60;}api_lasttime=millis();}//-----------------------------------------------------------------------------// Update thingspeak with new data from octoprint//-----------------------------------------------------------------------------//connect to thingspeakif(millis()-api2_lasttime>api2_mtbs||api2_lasttime==0){// Serial.print("connecting to ");//Serial.println(host);// Use WiFiClient class to create TCP connectionsWiFiClientclient;constinthttpPort=80;if(!client.connect(host,httpPort)){Serial.println("connection failed");return;}//check for POST commands//code adapted from zoomkat arduino forum post: http://forum.arduino.cc/index.php?topic=44646.0client.print(String("GET ")+"/channels/"+POSTid+"/feeds/last.json?api_key="+POSTReadApiKey+"&results=1 HTTP/1.1\r\n"+"Host: "+host+"\r\n"+"Connection: close\r\n\r\n");//updates values in printer thingspeak channel while(client.connected()&&!client.available())delay(1);//waits for datawhile(client.connected()||client.available()){//connected or data availablecharc=client.read();//gets byte from ethernet bufferTSPostString+=c;//places captured byte in TSPostString}TSPostString.remove(0,TSPostString.indexOf("{"));//isolate the json dataTSPostString.remove(TSPostString.indexOf("}")+1);//isolate the json dataSerial.println(TSPostString);StringfixedString=TSPostString;TSPostString="";//clear TSPostString variable//parsing//code adapted fromconstsize_tbufferSize=JSON_OBJECT_SIZE(6);DynamicJsonBufferjsonBuffer(bufferSize);charb[104];TSPostString.toCharArray(b,104);JsonObject&root=jsonBuffer.parseObject(fixedString);//json parametersconstchar*field1=root["field1"];// "1"constchar*field2=root["field2"];// "0"constchar*field3=root["field3"];// "0"constchar*field4=root["field4"];// "0"Serial.println("debug");Serial.println(field1);Serial.println(field2);Serial.println(field3);Serial.println(field4);postStart=String(field1);postCancel=String(field2);postRestart=String(field3);postPause=String(field4);if(postStart=="1"){api.octoPrintJobStart();Serial.print("Print started");}if(postCancel=="1"){api.octoPrintJobCancel();Serial.print("Print cancelled");}if(postRestart=="1"){api.octoPrintJobRestart();Serial.print("Print restarted");}if(postPause=="1"){api.octoPrintJobPauseResume();Serial.print("Print resumed/paused");}//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////TO DO: Clean Up, Parse, Connect to OctoPrint commands.//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////update data//updates values in printer thingspeak channelThingSpeak.setField(1,operational);ThingSpeak.setField(2,status);ThingSpeak.setField(3,toolTemp);ThingSpeak.setField(4,bedTemp);ThingSpeak.writeFields(printerID,printerWriteApiKey);Serial.print("TS printer channel updated");//updates values in job thingspeak channelThingSpeak.setField(1,fileName);ThingSpeak.setField(2,estimatedTimeHours);ThingSpeak.setField(3,estimatedTimeMinutes);ThingSpeak.setField(4,percentComplete);ThingSpeak.setField(5,timePrintedHours);ThingSpeak.setField(6,timePrintedMinutes);ThingSpeak.setField(7,timeLeftHours);ThingSpeak.setField(8,timeLeftMinutes);ThingSpeak.writeFields(jobID,jobWriteApiKey);delay(100);//Reset POST commandsclient.print(String("GET ")+"/update?api_key="+POSTWriteApiKey+"&field1=0&field2=0&field3=0&field4=0 HTTP/1.1\r\n"+"Host: "+host+"\r\n"+"Connection: close\r\n\r\n");if(debug==true){//serial print data: for debuggingSerial.println("Thingspeak Updated");Serial.println("operational = "+operational);Serial.println("status = "+status);Serial.println("tool temp = "+toolTemp);Serial.println("bed temp = "+bedTemp);Serial.println("file name = "+fileName);Serial.println("estimated print time = "+estimatedTimeMinutes);Serial.println("percent complete = "+percentComplete);Serial.println("hours printed = "+timePrintedHours);Serial.println("minutes printed = "+timePrintedMinutes);Serial.println("Hours remaining = "+timeLeftHours);Serial.println("mnutes remaining = "+timeLeftMinutes);}api2_lasttime=millis();}//-----------------------------------------------------------------------------// Check for Post commands//-----------------------------------------------------------------------------//-----------------------------------------------------------------------------// Display data using neopixels//-----------------------------------------------------------------------------if(operational=="0"){for(inti=0;i<=ringLength;i++){//display error color if experiencing an errorstrip.setPixelColor(i,error);}}else{if(status=="1"){drawRing(printing,percent);//display printing color on number of pixels representing print completion percentage}elseif(status=="2"){drawRing(paused,percent);//display paused color on number of pixels representing print completion percentage}else{if(background=1){for(inti=0;i<=ringLength;i++){strip.setPixelColor(i,standby);//display background color if a backround is wanted}}else{for(inti=0;i<=ringLength;i++){strip.setPixelColor(i,off);//turn all pixels off if no background is wanted}}}}strip.show();//show the pixels in their written state}voiddrawRing(uint32_tcolor,floatpercent){intpixelPercent=100/ringLength;// the percentage needed to fill one pixelintfullPixels=percent/(pixelPercent);//the number of pixels that should be lit up inti=0;while(i<fullPixels){//color all pixels up to fullPixelsstrip.setPixelColor(i,color);i++;}}