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.
121 lines
2.6 KiB
121 lines
2.6 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"
|
|
"log"
|
|
"net"
|
|
"sync"
|
|
)
|
|
|
|
func New(addr string) (lucifer3.Service, error) {
|
|
svc := &service{}
|
|
|
|
e := echo.New()
|
|
e.HideBanner = true
|
|
e.HidePort = true
|
|
|
|
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"`
|
|
}
|