0

I am quite a newbie in programming in python for a RPi (model 3B). I am using the RPi to run Octoprint which controls one of my 3D printers. The printer's power is connected via a TP-Link smart plug. I can control the plug via a plugin in Octoprint, but it does not allow me to switch the plug based on a GPIO input. In my situation I need the plug to switch its on/off state when I switch a rocker switch connected to a GPIO. In other words; when the GPIO input switches state (HIGH to LOW or vice versa), I need the TP-Link plug to switch as well (so ON to OFF or vice versa, depending on current state).

The plugin I am using has curl scripts using API that should make this possible. I am very new at this, but by running the example curl -s -H "Content-Type: application/json" -H "X-Api-Key: YOUR_API_KEY" -X POST -d '{ "command":"turnOn", "ip":"<ip of smartplug in settings>" }' http://YOUR_OCTOPRINT_SERVER/api/plugin/tplinksmartplug (with the required info) in a .py script triggered via an ssh terminal command, the plug indeed turns on. The same goes for the 'off' example. When I run this to get the status: curl -s -H "Content-Type: application/json" -H "X-Api-Key: MYAPIKEYHERE" -X POST -d '{ "command":"checkStatus", "ip":"xxx.xxx.xx.xx" }' http://xxx.xxx.xx.xxx/api/plugin/tplinksmartplug , this is the result when the power is indeed on: {"currentState":"on","emeter":null,"ip":"xxx.xxx.xx.xxx"}

Also, I achieved the rocker switch GPIO part before, enabling me to turn on and off the printer's lights via a relay. It is done by this code triggered in rc.local and works perfectly as I want it:

#!/usr/bin/env python
import RPi.GPIO as GPIO
from time import sleep

GPIO.setmode(GPIO.BOARD)

GPIO.setup(3, GPIO.OUT)
GPIO.setup(10, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)

relayState = 0
relayNeedsSwitch = 0
currentSwitchState = 0
oldSwitchState = 0

while True:
    if GPIO.input(10) == GPIO.HIGH:
        currentSwitchState = 1
    if GPIO.input(10) == GPIO.LOW:
        currentSwitchState = 0
    
    if currentSwitchState != oldSwitchState:
        print("SWITCHING RELAY")
        relayNeedsSwitch = 1
        
    if relayNeedsSwitch == 1:
        if GPIO.input(3) == GPIO.HIGH:
                GPIO.output(3, GPIO.LOW)
    else:
        GPIO.output(3, GPIO.HIGH)
        relayNeedsSwitch = 0
    
    oldSwitchState = currentSwitchState
    sleep(0.3)

Now the problem is that I cannot figure out how to combine the two successes. So how to sense the GPIO, when a switch is detected use curl to check the status of the plug, extracting the 'on' and 'off' variable from the output, and via curl change the status to the opposite (on/off). I tried integrating the curl commands in the GPIO script but it gives me syntax errors at the " signs. I have surfed the whole web, but haven't found a solution yet. If you know of a way a newbie can achieve this, please tell me. You will be a hero forever ;).

Anyway, thanks for reading this massive question!

  • You stated "I tried integrating the curl commands in the GPIO script but it gives me syntax errors at the " signs." Can you show the commands that caused the error? It sounds like you are close and perhaps can find the solution with the ```subprocess``` module – Jim Parker Jul 30 '20 at 21:39
  • Thanks a lot Jim! With `subprocess` I managed to solve the errors. Now I can switch the plug in my existing python code, however I still need to find out how to use the status message as a result from the curl as a variable. Do you have any idea about how to do that? – MrGnilhub Jul 31 '20 at 15:20

1 Answers1

0

As mentioned above, using the subprocess module will help with inter-process data sharing. To capture the output of a system call (such as curl, in your problem), use the .Popen and .communicate methods. See this other answer Store output of subprocess.Popen call in a string

Jim Parker
  • 1,095
  • 11
  • 16