Idea for a new plugin - hardware switch on gpio to command

I have a situation where it would be desirable to send a command (curl / API ) via a hardware switch (momentary?) connected to the PI's GPIO

My situation - I use PSU control plugin (a fork that does automatically connect when powered on , and powers the printer off when idle/cooled down)

Pi/Octoprint is on its own separate power supply and is on 24/7

The relay for the plugin is controlling the whole printer (screen, logic and all)

There are times I would like to power the printer on without having to fire up a PC/phone/tablet ...log into Ocotprint to get to the interface and click the power button in the web interface (eg for filament change/initiating a print from card)

A physical hardware button on or by the printer to send either an API or curl command to turn on (both of which are supported by the plugin I use as far as I am aware) would be ace

I know the plugin I use does allow turning off via gcode, and it may well accept turning on by gcode, but when the PSU goes off, of course I loose the ability to send gcode as there is no longer a printer that has power connected to the octoprint
(I do not use 5v line on the USB cable as I didn't want the LCD and logic on when the printer doesn't have power)

I'm sure if the plugin could accept a choice of GPIO pins as inputs and output a choice of system commands/API/curl and gcodes it would cover a lot of bases and be very handy for quite a lot of situations

Not a programmer so maybe I am asking for the moon on a stick?

Regards
Rob

2 Likes

Hi @Robocog!

Did you had a look on the OctoPrint-Enclosure already?
I use it to switch on and of the light for the printer: Via software and with a conventional push switch. This addon is very versatile.

1 Like

I did look at it- but I was worried as it seems to add a load of features I do not need and could possibly clash with the plugins I do use

I have just had an nodeMCU and got it talking to the API (or rather listening to it) by using the examples that came with the OcotprintAPI library

I have been playing with it and trying (and failed dismally) to get it to use the PSU Control API and get the status of the PSU and possibly toggle it - by playing with similar examples I have found and then trying to modify them (I am obviously out of my depth and trying to fit a programmers hat on a head that is better suited to other stuff)

I will give the enclosure plugin a try on a second PI as I dont want to break anything on the current one as it works so well

Regards
Rob

Here you go. I created these a while back and 4 printers later I really haven't had to change them and they work well enough for me. I don't have a wiring diagram on the repo but I'll try to add one soon.
It's just a simple pushbutton with a pulldown resistor.

Thanks Terry!
Have managed to implement your scripts (not wired any hardware up yet, but issuing the PSUOn.sh from command line via putty is indeed turning the power on!)

Have followed the instructions - and the listener is showing as started after a reboot
I have noticed it is using 100% CPU according to 'top' - should this be a concern?

Just about to Google how to wire a button with a pulldown resistor...(yea - this whole thing is that much of a new learning curve! and I am eternally grateful to those that have written and documented recipies / instructions and are willing to help those of us that would otherwise be totally out of our depth)

Regards
Rob

Glad I could help! Yeah I remember it took quite a bit of research to get it working. Had to study how to use the RPi GPIO pins with python which isn't my "native" programming language. lol I'm more at home with C on arduino stuff. Like hacking Marlin to do my bidding.

You've probably figured out the wiring by now but just for others who may stumble upon this thread, here's a link to a tutorial on pull up and pull down resistors:

About the 100% CPU, I get that too but then I don't think it's all because of the listener. Octoprint and plugins are written in Python so I would think that takes up most of the CPU time.

Cheers!

Thanks once again, it does work great

been trying to get the nodeMCU to send the

"curl -s -H "Content-Type: application/json" -H "X-Api-Key: MYAPIKEYISSECRET" -X POST -d '{ "command":"turnPSUOn" }' -u pi:mysecretpassword http://localhost/api/plugin/psucontrol"

  • but not having any joy
    Not given up on that idea as I do like the idea of not having to have a listener etc, but the hardware wired button thingy you have made does exactly what I need so the desire to get it working from the esp8266 I was given may lie dormant for now
    Regards
    Rob

Since you're not sending the command from the RPi, you need to change localhost to the RPi's IP address. localhost only works on the local machine. I like that idea of using a wireless device! A remote hardware switch.

Oh and also, if you were to implement your remote hardware switch from outside your home network and have port forwarding configured you would just substitute your_external_IP_address_or_domain:forwarded_port (ex. 65.38.3.33:8080) for localhost. I have a dynamic DNS domain so I use that.

I have got as far as using the examples from the Aurduino Octoprint API Library -I downloaded for the Arduino IDE and managed to send it to the nodeMCU and it works sucesfully - I have had it read the temps and the status of the printer, what job is running etc...
So it is connecting to the wifi, connecting and authenticating to Octoprint, I know what needs to be sent ...just dont know how to get it to send it :smiley: :smiley:
I found examples of sending json? stuff - but I had all sorts of strangeness trying to get it to compile and eventually it had me beat
I have been staring at the examples in the hopes I would start seeing a pattern and be able to suss out what needs to be changed or what phrases to Google to help me get my head round it...I did however print a nice little case for the nodeMCU so that I didn't feel totally useless :sunny:
Regards
Rob

Very interesting project. When you mentioned the ESP8266 I did start to look around for nodemcu code that mimis what cURL does. Also specific to using json as you did. I found some stuff but you probably found the same info. I'll go through them again and see if there's anything really promising for your application so I can post it here.

Cool, I have used Arduino before, but 99% of it was pre written and I modified it to try and fudge it for whatever I was working on

I found one ino that looked quite promising but it used ESP8266WiFi.h and whenever I tried to compile it I had an error to do with BearSSL and my Google foo on how to try and find its issue to try and resolve it only seemed to show me unrelated errors
(again I could have been putting the wrong phases into my search, which happens a lot when I try and do stuff I don't even know the terminology for..)

Regards
Rob

In the Adruino IDE software, you have to go visit the Manage Library screen and download the ESP8266WiFi library. If you get a particular error then during compilation, do a web search for that exact error message.

Hi - yes I did try that and it doesn't show ...I think it comes bundled with the esp8266 stuff I had to get to have the board recognised by the IDE - though I may be getting confused

I now have 2 lots of Arduino IDE - one is the Windows App store and one is the "normal" style (download/run the executable that installs it)

Just downloaded the stuff I need for the non Windows App store version to recognise the board (and I would assume is also gets the libraries it requires) - will try again with that one (assuming I can find the example I was playing with earlier!)
Regards
Rob

Not much info out there. Or rather, there's a lot of info but not all in one place. See if this http request works.

http.request{
url= "http://username:password@localhost/api/plugin/psucontrol",
method = "POST",
body = "command=turnPSUOn",
headers = {
["Content-Type"] = "Content-Type: application/json",
["X-Api-Key"] = "YOUR_API_KEY_FROM_OCTOPRINT"
}
}

The part I'm not completely certain about is the body argument. I can't seem to find documentation on how to format it for the http.request. I'd be very interested to see if this works in your project.

Sorry, I don't know what gave me the impression your were using Lua. Let me see what I can find for Arduino. Might actually be a lot easier.

I I would attempt LUA- but I also haven't managed to get esplorer to do anything with my ESP (other than it does connect, and the serial comms shows up)
If I try to do anything else it says it cannot connect..I have flashed the firmware (and boy was that a drama! had to use a cloud to compile it and it had what seemed a gazillion options...and I had not heard of ANY of them so just went with defaults so am amazed it does anything at all TBH!)

Regards
Rob

Yeah I wouldn't switch to Lua either. I'm more comfortable with Arduino at this point and it'll be easier to get things done. I have some working esp8266 scripts. Let me see if I can get it to send the URL as you're trying to do. I really like your project and I want to see it work.

Guess what. After hours of googling and testing I finally got my ESP to turn the printer on and off! Since this is your project, PM me and let me know how you want me to send you the code.

1 Like

You sir are a star! - and ALL the credit goes to you!
Please share it :smiley:

Just told my mrs that I will no longer be hunched over my PC quietly muttering to myself and grumbling into the monitor till the small hours - and she says thank you as well!

I managed to get LUA running via ESPlorer, but it seemed I needed to install a bunch of libraries - which I then thought I managed to do (via choclatey?) but I coudnt find how to convince ESPlorer that I had done this dance (if only it could have seen how many damn tabs I had open trying to research!)

Regards
Rob

1 Like

Thanks Rob! It's just too good an idea to pass up. Lol yeah, same here. I would say at least 15 tabs just for this project. Bits and pieces of information everywhere. Anyway, here's the code. Just add in your button handling.

/*
 * This sketch is proof of concept for accessing the Octoprint PSU Control plugin from an ESP8266.
 * Fill in SSID, PASSPHRASE, PRINTER_ADDRESS, PRINTER_USERNAME, PRINTER_PASSWORD, and API_KEY and compile.
 * From PSU Control documentation, valid commands are turnPSUOn, turnPSUOff, togglePSU, and getPSUState but I
 * have only tested turnPSUOn and turnPSUOff.
 * - Terry B.
 */ 
 
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <Arduino.h>

#ifndef STASSID
#define STASSID "YOUR_SSID"
#define STAPSK  "YOUR_PASSPHRASE"
#endif

const char* ssid     = STASSID;
const char* password = STAPSK;

#define PRINTER_ADDRESS  "http://YOUR_PRINTER_IP_ADDRESS_OR_FQDN:PORT_IF_NOT_80/api/plugin/psucontrol"
#define PRINTER_USERNAME "YOUR_USERNAME"
#define PRINTER_PASSWORD "YOUR_PASSWORD"
#define API_KEY          "YOUR_OCTOPRINT_API_KEY"

void setup() {
  Serial.begin(57600);

  // Connecting to WiFi network
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  /* Set the ESP8266 to be a WiFi-client only */
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void loop() {
   HTTPClient http;                                            //Declare object of class HTTPClient
   
   http.begin(PRINTER_ADDRESS);                                //Specify request destination
   http.setAuthorization(PRINTER_USERNAME, PRINTER_PASSWORD);
   http.addHeader("Content-Type", "application/json");         //Specify content-type header
   http.addHeader("X-Api-Key", API_KEY);
   int httpCode = http.POST("{\"command\":\"turnPSUOn\"}");    //Send command to printer
   String payload = http.getString();                          //For some reason we never actually get a response.
 
   Serial.println(httpCode);   //Print HTTP return code
   Serial.println(payload);    //Print request response payload
 
   http.end();  //Close connection
   delay(300000); // execute once every 5 minutes, don't flood remote service
}
3 Likes