first version
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"context"
|
||||
"rpirelay/config"
|
||||
"rpirelay/internal/api/relay"
|
||||
rt "rpirelay/internal/api/relay/transport"
|
||||
cc "rpirelay/internal/context"
|
||||
"rpirelay/internal/middleware"
|
||||
"rpirelay/internal/server"
|
||||
|
||||
"github.com/stianeikeland/go-rpio/v4"
|
||||
)
|
||||
|
||||
func Start(ctx context.Context, cfg *config.Config) chan error {
|
||||
errChan := make(chan error, 0)
|
||||
|
||||
go func() {
|
||||
if err := startAPIServer(ctx, cfg); err != nil {
|
||||
errChan <- err
|
||||
return
|
||||
}
|
||||
close(errChan)
|
||||
}()
|
||||
|
||||
return errChan
|
||||
}
|
||||
|
||||
func startAPIServer(ctx context.Context, cfg *config.Config) error {
|
||||
var err error
|
||||
|
||||
// init gpio
|
||||
err = rpio.Open()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer rpio.Close()
|
||||
|
||||
// set gpio pin
|
||||
relayPin := rpio.Pin(cfg.Server.RelayPin)
|
||||
// set pin mode output
|
||||
relayPin.Output()
|
||||
defer func() {
|
||||
relayPin.Low()
|
||||
}()
|
||||
|
||||
// new middleware
|
||||
mw := middleware.Initialize(cfg.Server.Secret)
|
||||
|
||||
svc := server.New(cfg)
|
||||
|
||||
apiGroup := svc.Group("/api")
|
||||
apiGroup.Use(cc.PatchContext(mw.APIPanicCatch()))
|
||||
{
|
||||
rt.NewHTTP(relay.Initialize(relayPin), apiGroup, mw.Authorization())
|
||||
}
|
||||
|
||||
svc.Start(ctx)
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package relay
|
||||
|
||||
import cc "rpirelay/internal/context"
|
||||
|
||||
var _ Service = (*Relay)(nil)
|
||||
|
||||
func (r *Relay) SwitchOn(c *cc.C) (err error) {
|
||||
r.pin.High()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Relay) SwitchOff(c *cc.C) (err error) {
|
||||
r.pin.Low()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *Relay) GetState(c *cc.C) (open bool, err error) {
|
||||
state := r.pin.Read()
|
||||
|
||||
return state == 1, nil
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package relay
|
||||
|
||||
import (
|
||||
cc "rpirelay/internal/context"
|
||||
|
||||
"github.com/stianeikeland/go-rpio/v4"
|
||||
)
|
||||
|
||||
func Initialize(pin rpio.Pin) *Relay {
|
||||
return &Relay{pin: pin}
|
||||
}
|
||||
|
||||
type Relay struct {
|
||||
pin rpio.Pin
|
||||
}
|
||||
|
||||
type Service interface {
|
||||
SwitchOn(c *cc.C) (err error)
|
||||
SwitchOff(c *cc.C) (err error)
|
||||
GetState(c *cc.C) (open bool, err error)
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
package transport
|
||||
|
||||
import (
|
||||
"rpirelay/internal/api/relay"
|
||||
|
||||
cc "rpirelay/internal/context"
|
||||
apierr "rpirelay/internal/errors"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type HTTP struct {
|
||||
svc relay.Service
|
||||
}
|
||||
|
||||
func NewHTTP(svc relay.Service, e *gin.RouterGroup, authorizationMW cc.CustomHandler) {
|
||||
h := &HTTP{svc: svc}
|
||||
patch := cc.PatchContext
|
||||
|
||||
g := e.Group("/relay")
|
||||
g.Use(patch(authorizationMW))
|
||||
|
||||
// swagger:route POST /api/relay/on relay switchOn
|
||||
// set relay on
|
||||
// security:
|
||||
// api_key:
|
||||
// responses:
|
||||
// default: respDefault
|
||||
g.POST("/on", patch(h.switchOn()))
|
||||
|
||||
// swagger:route POST /api/relay/off relay switchOff
|
||||
// set relay off
|
||||
// security:
|
||||
// api_key:
|
||||
// responses:
|
||||
// default: respDefault
|
||||
g.POST("/off", patch(h.switchOff()))
|
||||
|
||||
// swagger:route GET /api/relay relay getState
|
||||
// get relay state
|
||||
// security:
|
||||
// api_key:
|
||||
// responses:
|
||||
// 200: relayStateResp
|
||||
// default: respDefault
|
||||
g.GET("/", patch(h.getState()))
|
||||
g.GET("", patch(h.getState()))
|
||||
}
|
||||
|
||||
func (h *HTTP) switchOn() cc.CustomHandler {
|
||||
return func(c *cc.C) {
|
||||
if err := h.svc.SwitchOn(c); err != nil {
|
||||
panic(apierr.ErrInternalError.SetErr(errors.WithStack(err)))
|
||||
}
|
||||
|
||||
c.Success()
|
||||
}
|
||||
}
|
||||
|
||||
func (h *HTTP) switchOff() cc.CustomHandler {
|
||||
return func(c *cc.C) {
|
||||
if err := h.svc.SwitchOff(c); err != nil {
|
||||
panic(apierr.ErrInternalError.SetErr(errors.WithStack(err)))
|
||||
}
|
||||
|
||||
c.Success()
|
||||
}
|
||||
}
|
||||
|
||||
type relayStateResp struct {
|
||||
Open bool `json:"open"`
|
||||
}
|
||||
|
||||
func (h *HTTP) getState() cc.CustomHandler {
|
||||
return func(c *cc.C) {
|
||||
open, err := h.svc.GetState(c)
|
||||
if err != nil {
|
||||
panic(apierr.ErrInternalError.SetErr(errors.WithStack(err)))
|
||||
}
|
||||
|
||||
resp := relayStateResp{Open: open}
|
||||
|
||||
c.Success(resp)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package transport
|
||||
|
||||
// swagger:response relayStateResp
|
||||
type swaggRelayStateResp struct {
|
||||
// in: body
|
||||
Body relayStateResp
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
// RPI Relay API.
|
||||
//
|
||||
// Terms Of Service:
|
||||
//
|
||||
// there are no TOS at this moment, use at your own risk we take no responsibility
|
||||
//
|
||||
// Schemes: http, https
|
||||
// Host: localhost
|
||||
// BasePath: /
|
||||
// Version: 0.0.1
|
||||
//
|
||||
// Consumes:
|
||||
// - application/json
|
||||
//
|
||||
// Produces:
|
||||
// - application/json
|
||||
//
|
||||
// SecurityDefinitions:
|
||||
// api_key:
|
||||
// type: apiKey
|
||||
// name: X-Lawsnote-Key
|
||||
// in: header
|
||||
// description: secret
|
||||
//
|
||||
// swagger:meta
|
||||
package api
|
||||
Reference in New Issue
Block a user