You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

123 lines
2.7 KiB

package httpapiv1
import (
lucifer3 "git.aiterp.net/lucifer3/server"
"git.aiterp.net/lucifer3/server/commands"
"git.aiterp.net/lucifer3/server/effects"
"git.aiterp.net/lucifer3/server/events"
"git.aiterp.net/lucifer3/server/services/uistate"
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
"log"
"net"
"sync"
)
func New(addr string) (lucifer3.Service, error) {
svc := &service{}
e := echo.New()
e.HideBanner = true
e.HidePort = true
e.Use(middleware.CORS())
e.GET("/state", func(c echo.Context) error {
svc.mu.Lock()
data := svc.data
svc.mu.Unlock()
return c.JSON(200, data)
})
e.POST("/command", func(c echo.Context) error {
var input commandInput
err := c.Bind(&input)
if err != nil {
return err
}
svc.mu.Lock()
bus := svc.bus
svc.mu.Unlock()
if bus == nil {
return c.String(413, "Waiting for bus")
}
switch {
case input.Assign != nil:
bus.RunCommand(commands.Assign{
ID: nil,
Match: input.Assign.Match,
Effect: input.Assign.Effect.Effect,
})
case input.PairDevice != nil:
bus.RunCommand(*input.PairDevice)
case input.ForgetDevice != nil:
bus.RunCommand(*input.ForgetDevice)
case input.SearchDevices != nil:
bus.RunCommand(*input.SearchDevices)
case input.AddAlias != nil:
bus.RunCommand(*input.AddAlias)
case input.RemoveAlias != nil:
bus.RunCommand(*input.RemoveAlias)
default:
return c.String(400, "No supported command found in input")
}
return c.JSON(200, input)
})
listener, err := net.Listen("tcp", addr)
if err != nil {
return nil, err
}
e.Listener = listener
go func() {
err := e.Start(addr)
if err != nil {
log.Fatalln("Failed to listen to webserver")
}
}()
return svc, nil
}
type service struct {
mu sync.Mutex
data uistate.Data
bus *lucifer3.EventBus
}
func (s *service) Active() bool {
return true
}
func (s *service) HandleEvent(bus *lucifer3.EventBus, event lucifer3.Event) {
switch event := event.(type) {
case events.Started:
s.mu.Lock()
s.bus = bus
s.mu.Unlock()
case uistate.Patch:
s.mu.Lock()
s.data = s.data.WithPatch(event)
s.mu.Unlock()
// TODO: Broadcast websockets
}
}
type commandInput struct {
Assign *assignInput `json:"assign,omitempty"`
AddAlias *commands.AddAlias `json:"addAlias,omitempty"`
RemoveAlias *commands.RemoveAlias `json:"removeAlias,omitempty"`
PairDevice *commands.PairDevice `json:"pairDevice,omitempty"`
SearchDevices *commands.SearchDevices `json:"searchDevices,omitempty"`
ForgetDevice *commands.ForgetDevice `json:"forgetDevice,omitempty"`
}
type assignInput struct {
Match string `json:"match"`
Effect effects.Serializable `json:"effect"`
}