package main

import (
	"fmt"
	"github.com/stianeikeland/go-rpio"
	"net/http"
	"os"
)

var (
	pin = rpio.Pin(23)
)

func main() {
	// Open and map memory to access gpio, check for errors
	if err := rpio.Open(); err != nil {
		fmt.Println(err)
		os.Exit(1)
	}

	// Pull up pin
	pin.PullUp()

	// Unmap gpio memory when done
	defer rpio.Close()

	http.HandleFunc("/", handler)
	http.ListenAndServe(":80", nil)
}

func handler(w http.ResponseWriter, r *http.Request) {
	doorStatus := pin.Read()
	var doorString string
	if doorStatus == 0 {
		doorString = "closed"
	} else {
		doorString = "open"
	}

	fmt.Fprintln(w, "Garage door is:", doorString)
}

package main

import (
	"fmt"
	"github.com/stianeikeland/go-rpio"
	"net/http"
)

type DoorStatus int

const (
	OPEN DoorStatus = iota
	CLOSED
)

type StatusRequest struct {
	resultChan chan DoorStatus
}

func main() {
	statusChan := make(chan *StatusRequest)
	go doorMonitor(statusChan)

	http.Handle("/", &StatusPage{statusChan})
	http.ListenAndServe(":80", nil)
}

func doorMonitor(queue chan *StatusRequest) {
	// Open and map memory to access gpio, check for errors
	if err := rpio.Open(); err != nil {
		panic(err)
	}

	pin := rpio.Pin(23)

	// Pull up pin
	pin.PullUp()

	for req := range queue {
		doorStatus := pin.Read()
		if doorStatus == 0 {
			req.resultChan <- CLOSED
		} else {
			req.resultChan <- OPEN
		}
	}

	// Unmap gpio memory when done
	defer rpio.Close()
}

type StatusPage struct {
	statusChan chan *StatusRequest
}

func (s *StatusPage) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	req := &StatusRequest{make(chan DoorStatus)}
	s.statusChan <- req
	doorStatus := <-req.resultChan
	var doorString string
	if doorStatus == CLOSED {
		doorString = "closed"
	} else {
		doorString = "open"
	}

	fmt.Fprintln(w, "Garage door is:", doorString)
}

Put door monitoring in a function, use channels.
Put door monitoring in a function, use channels.
