Python Forum
Webhook, post_data, GPIO partial changes - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: Webhook, post_data, GPIO partial changes (/thread-38670.html)



Webhook, post_data, GPIO partial changes - DigitalID - Nov-10-2022

Okay,

I am a project oriented integrator, so I don't code on a regular basis, and I switch a lot between Arduino and Raspberry Pi, based on what the application is. I can usually search for examples and posts with similar problems and eventually find work arounds for my hang-ups. In this case, my project is 80% is working, but I don't know what to search for to close the loop. I am working on a solution that listens for webhooks and sets a number of outputs based on the matching statements.

Basically the problem I am having is, I have one source feeding statements, and I have two banks of 8 outputs that should be independent from each other. My assumption is that GPIOs that are nested in an if statement should change, but GPIOs that are not listed should be ignored and left alone. My captures are working fine, and the initial function turns on and off the GPIOs as desired. The problem is that the other bank of 8 GPIOs that are not listed all turn off even there was nothing telling it to, when they should be left alone. One set of statements should only work for the fist bank of 8, leaving the other bank of 8 alone, and the next set of statements should only affect the second bank of GPIOs, leaving the first bank of GPIOs alone. I'll pot the code and see if this enough of an explanation to illuminate the missing elements:

#!/usr/bin/env python3

import RPi.GPIO as GPIO
import os
from http.server import BaseHTTPRequestHandler, HTTPServer

host_name = '192.168.1.107'  # IP Address of Raspberry Pi
host_port = 8000


def setupGPIO():
    GPIO.setmode(GPIO.BCM)
    GPIO.setwarnings(False)

    GPIO.setup(4, GPIO.OUT, initial=GPIO.HIGH) # Set pin 4 to be an output pin and set initial value to HIGH (off)
    GPIO.setup(5, GPIO.OUT, initial=GPIO.HIGH) # Set pin 5 to be an output pin and set initial value to HIGH (off)
    GPIO.setup(6, GPIO.OUT, initial=GPIO.HIGH) # Set pin 6 to be an output pin and set initial value to HIGH (off)
    GPIO.setup(7, GPIO.OUT, initial=GPIO.HIGH) # Set pin 7 to be an output pin and set initial value to HIGH (off)
    GPIO.setup(8, GPIO.OUT, initial=GPIO.HIGH) # Set pin 8 to be an output pin and set initial value to HIGH (off)
    GPIO.setup(9, GPIO.OUT, initial=GPIO.HIGH) # Set pin 9 to be an output pin and set initial value to HIGH (off)
    GPIO.setup(10, GPIO.OUT, initial=GPIO.HIGH) # Set pin 10 to be an output pin and set initial value to HIGH (off)
    GPIO.setup(11, GPIO.OUT, initial=GPIO.HIGH) # Set pin 11 to be an output pin and set initial value to HIGH (off)
    
    GPIO.setup(12, GPIO.OUT, initial=GPIO.HIGH) # Set pin 12 to be an output pin and set initial value to HIGH (off)
    GPIO.setup(13, GPIO.OUT, initial=GPIO.HIGH) # Set pin 13 to be an output pin and set initial value to HIGH (off)
    GPIO.setup(14, GPIO.OUT, initial=GPIO.HIGH) # Set pin 14 to be an output pin and set initial value to HIGH (off)
    GPIO.setup(15, GPIO.OUT, initial=GPIO.HIGH) # Set pin 15 to be an output pin and set initial value to HIGH (off)
    GPIO.setup(16, GPIO.OUT, initial=GPIO.HIGH) # Set pin 16 to be an output pin and set initial value to HIGH (off)
    GPIO.setup(17, GPIO.OUT, initial=GPIO.HIGH) # Set pin 17 to be an output pin and set initial value to HIGH (off)
    GPIO.setup(18, GPIO.OUT, initial=GPIO.HIGH) # Set pin 18 to be an output pin and set initial value to HIGH (off)
    GPIO.setup(19, GPIO.OUT, initial=GPIO.HIGH) # Set pin 19 to be an output pin and set initial value to HIGH (off)


def getTemperature():
    temp = os.popen("/opt/vc/bin/vcgencmd measure_temp").read()
    return temp


class MyServer(BaseHTTPRequestHandler):

    def do_HEAD(self):
        self.send_response(200)
        self.send_header('Content-type', 'text/html')
        self.end_headers()

    def _redirect(self, path):
        self.send_response(303)
        self.send_header('Content-type', 'text/html')
        self.send_header('Location', path)
        self.end_headers()

    def do_GET(self):
        html = '''
           <html>
           <body 
            style="width:960px; margin: 20px auto;">
           <h1>Welcome to my Raspberry Pi</h1>
           <p>Current GPU temperature is {}</p>
           <form action="/" method="POST">
               Turn LED :
               <input type="submit" name="submit" value="C1PGMON">
               <input type="submit" name="submit" value="C1PGMOFF">
           </form>
           </body>
           </html>
        '''
        temp = getTemperature()
        self.do_HEAD()
        self.wfile.write(html.format(temp[5:]).encode("utf-8"))

    def do_POST(self):

        content_length = int(self.headers['Content-Length'])
        post_data = self.rfile.read(content_length).decode("utf-8")
        post_data = post_data.split("=")[1]

        setupGPIO()

        if post_data == 'C1PGMON':
            GPIO.output(4, GPIO.LOW)
            GPIO.output(5, GPIO.HIGH)
            GPIO.output(6, GPIO.HIGH)
            GPIO.output(7, GPIO.HIGH)
            GPIO.output(8, GPIO.HIGH)
            GPIO.output(9, GPIO.HIGH)
            GPIO.output(10, GPIO.HIGH)
            GPIO.output(11, GPIO.HIGH)
                    
        if post_data == 'C2PGMON':
            GPIO.output(4, GPIO.HIGH)
            GPIO.output(5, GPIO.LOW)
            GPIO.output(6, GPIO.HIGH)
            GPIO.output(7, GPIO.HIGH)
            GPIO.output(8, GPIO.HIGH)
            GPIO.output(9, GPIO.HIGH)
            GPIO.output(10, GPIO.HIGH)
            GPIO.output(11, GPIO.HIGH)
            
        if post_data == 'C3PGMON':
            GPIO.output(4, GPIO.HIGH)
            GPIO.output(5, GPIO.HIGH)
            GPIO.output(6, GPIO.LOW)
            GPIO.output(7, GPIO.HIGH)
            GPIO.output(8, GPIO.HIGH)
            GPIO.output(9, GPIO.HIGH)
            GPIO.output(10, GPIO.HIGH)
            GPIO.output(11, GPIO.HIGH)
            
        if post_data == 'C4PGMON':
            GPIO.output(4, GPIO.HIGH)
            GPIO.output(5, GPIO.HIGH)
            GPIO.output(6, GPIO.HIGH)
            GPIO.output(7, GPIO.LOW)
            GPIO.output(8, GPIO.HIGH)
            GPIO.output(9, GPIO.HIGH)
            GPIO.output(10, GPIO.HIGH)
            GPIO.output(11, GPIO.HIGH)
            
        if post_data == 'C5PGMON':
            GPIO.output(4, GPIO.HIGH)
            GPIO.output(5, GPIO.HIGH)
            GPIO.output(6, GPIO.HIGH)
            GPIO.output(7, GPIO.HIGH)
            GPIO.output(8, GPIO.LOW)
            GPIO.output(9, GPIO.HIGH)
            GPIO.output(10, GPIO.HIGH)
            GPIO.output(11, GPIO.HIGH)
                    
        if post_data == 'C6PGMON':
            GPIO.output(4, GPIO.HIGH)
            GPIO.output(5, GPIO.HIGH)
            GPIO.output(6, GPIO.HIGH)
            GPIO.output(7, GPIO.HIGH)
            GPIO.output(8, GPIO.HIGH)
            GPIO.output(9, GPIO.LOW)
            GPIO.output(10, GPIO.HIGH)
            GPIO.output(11, GPIO.HIGH)
            
        if post_data == 'C7PGMON':
            GPIO.output(4, GPIO.HIGH)
            GPIO.output(5, GPIO.HIGH)
            GPIO.output(6, GPIO.HIGH)
            GPIO.output(7, GPIO.HIGH)
            GPIO.output(8, GPIO.HIGH)
            GPIO.output(9, GPIO.HIGH)
            GPIO.output(10, GPIO.LOW)
            GPIO.output(11, GPIO.HIGH)
            
        if post_data == 'C8PGMON':
            GPIO.output(4, GPIO.HIGH)
            GPIO.output(5, GPIO.HIGH)
            GPIO.output(6, GPIO.HIGH)
            GPIO.output(7, GPIO.HIGH)
            GPIO.output(8, GPIO.HIGH)
            GPIO.output(9, GPIO.HIGH)
            GPIO.output(10, GPIO.HIGH)
            GPIO.output(11, GPIO.LOW)
            
        if post_data == 'C1PVWON':
            GPIO.output(12, GPIO.LOW)
            GPIO.output(13, GPIO.HIGH)
            GPIO.output(14, GPIO.HIGH)
            GPIO.output(15, GPIO.HIGH)
            GPIO.output(16, GPIO.HIGH)
            GPIO.output(17, GPIO.HIGH)
            GPIO.output(18, GPIO.HIGH)
            GPIO.output(19, GPIO.HIGH)
            
        if post_data == 'C2PVWON':
            GPIO.output(12, GPIO.HIGH)
            GPIO.output(13, GPIO.LOW)
            GPIO.output(14, GPIO.HIGH)
            GPIO.output(15, GPIO.HIGH)
            GPIO.output(16, GPIO.HIGH)
            GPIO.output(17, GPIO.HIGH)
            GPIO.output(18, GPIO.HIGH)
            GPIO.output(19, GPIO.HIGH)
            
        if post_data == 'C3PVWON':
            GPIO.output(12, GPIO.HIGH)
            GPIO.output(13, GPIO.HIGH)
            GPIO.output(14, GPIO.LOW)
            GPIO.output(15, GPIO.HIGH)
            GPIO.output(16, GPIO.HIGH)
            GPIO.output(17, GPIO.HIGH)
            GPIO.output(18, GPIO.HIGH)
            GPIO.output(19, GPIO.HIGH)
            
        if post_data == 'C4PVWON':
            GPIO.output(12, GPIO.HIGH)
            GPIO.output(13, GPIO.HIGH)
            GPIO.output(14, GPIO.HIGH)
            GPIO.output(15, GPIO.LOW)
            GPIO.output(16, GPIO.HIGH)
            GPIO.output(17, GPIO.HIGH)
            GPIO.output(18, GPIO.HIGH)
            GPIO.output(19, GPIO.HIGH)
            
        if post_data == 'C5PVWON':
            GPIO.output(12, GPIO.HIGH)
            GPIO.output(13, GPIO.HIGH)
            GPIO.output(14, GPIO.HIGH)
            GPIO.output(15, GPIO.HIGH)
            GPIO.output(16, GPIO.LOW)
            GPIO.output(17, GPIO.HIGH)
            GPIO.output(18, GPIO.HIGH)
            GPIO.output(19, GPIO.HIGH)
            
        if post_data == 'C6PVWON':
            GPIO.output(12, GPIO.HIGH)
            GPIO.output(13, GPIO.HIGH)
            GPIO.output(14, GPIO.HIGH)
            GPIO.output(15, GPIO.HIGH)
            GPIO.output(16, GPIO.HIGH)
            GPIO.output(17, GPIO.LOW)
            GPIO.output(18, GPIO.HIGH)
            GPIO.output(19, GPIO.HIGH)
            
        if post_data == 'C7PVWON':
            GPIO.output(12, GPIO.HIGH)
            GPIO.output(13, GPIO.HIGH)
            GPIO.output(14, GPIO.HIGH)
            GPIO.output(15, GPIO.HIGH)
            GPIO.output(16, GPIO.HIGH)
            GPIO.output(17, GPIO.HIGH)
            GPIO.output(18, GPIO.LOW)
            GPIO.output(19, GPIO.HIGH)
            
        if post_data == 'C8PVWON':
            GPIO.output(12, GPIO.HIGH)
            GPIO.output(13, GPIO.HIGH)
            GPIO.output(14, GPIO.HIGH)
            GPIO.output(15, GPIO.HIGH)
            GPIO.output(16, GPIO.HIGH)
            GPIO.output(17, GPIO.HIGH)
            GPIO.output(18, GPIO.HIGH)
            GPIO.output(19, GPIO.LOW)
        
        print("LED is {}".format(post_data))
        self._redirect('/')  # Redirect back to the root url


# # # # # Main # # # # #

if __name__ == '__main__':
    http_server = HTTPServer((host_name, host_port), MyServer)
    print("Server Starts - %s:%s" % (host_name, host_port))

    try:
        http_server.serve_forever()
    except KeyboardInterrupt:
        http_server.server_close()



RE: Webhook, post_data, GPIO partial changes - Larz60+ - Nov-10-2022

you should use bitmaps and masking.
There are examples available: one with bitmap response:
https://stackoverflow.com/questions/8508799/bit-masking-in-python
see answer: https://stackoverflow.com/a/8508963

more
google: 'bitmasks python'


RE: Webhook, post_data, GPIO partial changes - deanhystad - Nov-10-2022

You call this each time do_POST() runs.
        setupGPIO()
And that sets all the outputs high.

Since the message is structured text, why not pull the information out of the message? The message format is C(index)P(group)MON where index is a digit from 1-8 and group is G or V. It is easy to write a regex that not only verifies the message but extracts the index and group information.
import re

def do_POST(message):
    try:
        pin, group = re.match(r'C([1-8])P(G|V)MON', message).groups()
        print(group, pin)
    except:
        print(message, "is invalid")

while True:
    do_POST(input("Enter Message: "))
Output:
>>> python test.py Enter Message: arfarf arfarf is invalid Enter Message: C7PGMON G 7 Enter Message: C3PVMON V 3
Knowing the group and index, it is easy to map this to a particular output.
import RPi_GPIO as GPIO
import re

# Define the LED groups.
led_groups = {
    "G":(4, 5, 6, 7, 8, 9, 10, 11),
    "V":(12, 13, 14, 15, 16, 17, 18, 19)
}

# Process a message
def do_POST(message):
    try:
        pin, group = re.match(r'C([1-8])P(G|V)MON', message).groups()
        group = led_groups[group]
        pin = group[int(pin)-1]
        for p in group:
            print(p, "=", GPIO.LOW if p == pin else GPIO.HIGH)
    except:
        print(message, "is invalid")

while True:
    do_POST(input("Enter Message: "))
Output:
>>> python test.py Enter Message: C7PVMON 12 = 1 13 = 1 14 = 1 15 = 1 16 = 1 17 = 1 18 = 0 19 = 1 Enter Message:
And since there are lists of outputs, may as well use those to initialize the GPIO outputs.
import RPi_GPIO as GPIO
import re

# Define the LED groups.
led_groups = {
    "G":(4, 5, 6, 7, 8, 9, 10, 11),
    "V":(12, 13, 14, 15, 16, 17, 18, 19)
}

# Initalize outputs used to turn LED's on/off
def setupGPIO():
    GPIO.setmode(GPIO.BCM)
    GPIO.setwarnings(False)
    for group in led_groups.values():
        for pin in group:
            GPIO.setup(pin, GPIO.OUT, initial=GPIO.HIGH)


# Process a message
def do_POST(message):
    try:
        pin, group = re.match(r'C([1-8])P(G|V)MON', message).groups()
        group = led_groups[group]
        pin = group[int(pin)-1]
        for p in group:
            GPIO.output(p, GPIO.LOW if p == pin else GPIO.HIGH)
    except:
        print(message, "is invalid")

if __name__ == '__main__':
    setupGPIO()  # This setup code belongs down here, not in do_post
    while True:
        do_POST(input("Enter Message: "))