Supereg / homebridge-http-switch

Powerful http switch for Homebridge: https://github.com/homebridge/homebridge
ISC License
219 stars 36 forks source link

Cannot correctly pass statusUrl request. #65

Closed Conner-Killian closed 4 years ago

Conner-Killian commented 4 years ago

I've been struggling with this for almost a day now and cannot get my head around it. It would be great if I could get some assistance.

I've set up a Python HTTP server for a Relay that controls a light switch. Heres the main HTTP and relay control file:

import SocketServer
from BaseHTTPServer import BaseHTTPRequestHandler
import RPi.GPIO as GPIO

def on():
    print "on"
    GPIO.setwarnings(False)
    GPIO.setmode(GPIO.BOARD)
    GPIO.setup(12, GPIO.OUT)
    GPIO.output(12,1)

def off():
    print "off"
    GPIO.setwarnings(False)
    GPIO.setmode(GPIO.BOARD)
    GPIO.setup(12, GPIO.OUT)
    GPIO.output(12,0)
    GPIO.cleanup()

def checkStatus():
    GPIO.setwarnings(False)
    GPIO.setmode(GPIO.BOARD)
    GPIO.setup(12, GPIO.OUT)
    status = GPIO.input(12)
    if status:
        return '1'
    else:
        return '0'

class GetHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        if self.path == '/on':
            on()
            self.send_response(200)
        if self.path == '/off':
            off()
            self.send_response(200)
        if self.path == '/status':
            statusValue = checkStatus()
            self.send_response(200)
            self.end_headers()
            self.wfile.write("% s" % statusValue)
            return

if __name__ == '__main__':
    from BaseHTTPServer import HTTPServer
    server = HTTPServer(("", 8080), GetHandler)
    print 'Starting server, use <Ctrl-C> to stop'
    server.serve_forever()

I don't know what I'm doing wrong here. Each time I try and request http://xxx.xxx.x.xxx:8080/status I get this error on HomeBridge:

[7/24/2020, 1:31:01 PM] [Switch] Error occurred setting state of switch: socket hang up
[7/24/2020, 1:31:01 PM] [Switch] Error: socket hang up
    at connResetException (internal/errors.js:610:14)
    at Socket.socketOnEnd (_http_client.js:453:23)
    at Socket.emit (events.js:327:22)
    at endReadableNT (_stream_readable.js:1220:12)
    at processTicksAndRejections (internal/process/task_queues.js:84:21) {
  code: 'ECONNRESET'
}

Your help will be much appreciated :)

Supereg commented 4 years ago

„Socket hang up“ sounds like the Connection isn’t properly terminated. I’m not familiar with the python http api. Do you properly close the http connection after sending the response?

Conner-Killian commented 4 years ago

„Socket hang up“ sounds like the Connection isn’t properly terminated. I’m not familiar with the python http api. Do you properly close the http connection after sending the response?

I believe so. I can retrieve the status response perfectly through typical curl.

I'm tempted to just redo the whole thing in another language. What language do you recommend that I code the HTTP server in?

Conner-Killian commented 4 years ago

Closing this thread. I found my issue with the code. This code was in Python 2.x which I thought would work just fine. I redid the code in Python 3.x and used the http.server library instead.

Here's the code for those who want to use it in the future or for curiosity:

from http.server import BaseHTTPRequestHandler
import RPi.GPIO as GPIO

def on():
    print("on")
    GPIO.setwarnings(False)
    GPIO.setmode(GPIO.BOARD)
    GPIO.setup(12, GPIO.OUT)
    GPIO.output(12,1)

def off():
    print("off")
    GPIO.setwarnings(False)
    GPIO.setmode(GPIO.BOARD)
    GPIO.setup(12, GPIO.OUT)
    GPIO.output(12,0)
    GPIO.cleanup()

def checkStatus():
    GPIO.setwarnings(False)
    GPIO.setmode(GPIO.BOARD)
    GPIO.setup(12, GPIO.OUT)
    status = GPIO.input(12)
    if status:
        return b'1'
    else:
        return b'0'

class GetHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        if self.path == '/on':
            on()
            self.send_response(200)
            self.end_headers()
        if self.path == '/off':
            off()
            self.send_response(200)
            self.end_headers()
        if self.path == '/status':
            statusValue = checkStatus()
            self.send_response(200)
            self.end_headers()
        statusValue = checkStatus()
        self.wfile.write(statusValue)
        return

if __name__ == '__main__':
    from http.server import HTTPServer
    server = HTTPServer(("", 8080), GetHandler)
    print('Starting server, use <Ctrl-C> to stop')
    server.serve_forever()

Thanks for your help @Supereg!

Supereg commented 4 years ago

👍🏽