Browse Source

Mill: maybe wifi?

beelzebub
Stian Fredrik Aune 2 years ago
parent
commit
865dd1994a
  1. 2
      services/mill/online.go
  2. 151
      services/mill/wifi.go

2
services/mill/online.go

@ -85,6 +85,8 @@ func (o *OnlineBridge) Start() {
o.started = true o.started = true
go func() { go func() {
defer func() { defer func() {
recover()
log.Printf("Mill: %s stopped unexpectedly", o.ID) log.Printf("Mill: %s stopped unexpectedly", o.ID)
o.started = false o.started = false
}() }()

151
services/mill/wifi.go

@ -1,16 +1,27 @@
package mill package mill
import ( import (
"bytes"
"encoding/json"
"fmt"
lucifer3 "git.aiterp.net/lucifer3/server" lucifer3 "git.aiterp.net/lucifer3/server"
"git.aiterp.net/lucifer3/server/device" "git.aiterp.net/lucifer3/server/device"
"git.aiterp.net/lucifer3/server/events"
"git.aiterp.net/lucifer3/server/internal/gentools"
"log"
"math"
"net/http"
"strings" "strings"
"sync" "sync"
"time"
) )
type WifiBridge struct { type WifiBridge struct {
ID string ID string
IP string IP string
state *device.State
mx sync.Mutex mx sync.Mutex
started bool started bool
bus *lucifer3.EventBus bus *lucifer3.EventBus
@ -21,7 +32,7 @@ func (w *WifiBridge) SetBus(bus *lucifer3.EventBus) {
} }
func (w *WifiBridge) SetState(id string, state device.State) bool { func (w *WifiBridge) SetState(id string, state device.State) bool {
if !strings.HasPrefix(id, "mill:3:"+w.IP) {
if !strings.HasPrefix(id, w.ID) {
return false return false
} }
@ -29,11 +40,149 @@ func (w *WifiBridge) SetState(id string, state device.State) bool {
} }
func (w *WifiBridge) Start() { func (w *WifiBridge) Start() {
if err := w.refresh(); err != nil {
w.bus.RunEvent(deviceFailed(w.ID, err))
return
}
w.started = true
go func() { go func() {
defer func() {
recover()
log.Printf("Mill: %s stopped unexpectedly", o.ID)
w.started = false
}()
for {
time.Sleep(1 * time.Minute)
if err := w.refresh(); err != nil {
w.bus.RunEvent(deviceFailed(w.ID, err))
break
}
}
}() }()
} }
func (w *WifiBridge) IsStarted() bool { func (w *WifiBridge) IsStarted() bool {
return w.started return w.started
} }
func (w *WifiBridge) refresh() error {
w.mx.Lock()
defer w.mx.Unlock()
temp, err := w.getTemperature()
if err != nil {
return err
}
if w.state != nil {
w.state = &device.State{
Temperature: gentools.Ptr(temp),
}
w.bus.RunEvent(events.DeviceReady{ID: w.ID})
w.bus.RunEvent(events.HardwareMetadata{ID: w.ID, Icon: "heater"})
w.bus.RunEvent(events.HardwareState{
ID: w.ID,
InternalName: "Mill heater @ " + w.IP,
SupportFlags: device.SFlagTemperature,
State: *w.state,
})
}
w.state.Temperature = gentools.Ptr(*w.state.Temperature - math.Mod(*w.state.Temperature, 0.5))
if math.Abs(temp-*w.state.Temperature) >= 0.1 {
if err := w.writeTemperature(); err != nil {
return err
}
}
}
func (w *WifiBridge) getTemperature() (float64, error) {
body, err := json.Marshal(getSetTemperatureBody{Type: "Normal"})
if err != nil {
return 0.0, err
}
req, err := http.NewRequest(
"GET",
"http://%s/set-temperature",
bytes.NewReader(body),
)
if err != nil {
return 0.0, err
}
res, err := http.DefaultClient.Do(req)
if err != nil {
return 0.0, err
}
var resBody getSetTemperatureResponse
err = json.NewDecoder(res.Body).Decode(&resBody)
if err != nil || resBody.Status != "ok" {
return 0.0, fmt.Errorf("refresh failed %s (bad response from query)", w.ID)
}
return resBody.Value, nil
}
func (w *WifiBridge) writeTemperature() error {
body, err := json.Marshal(postSetTemperatureBody{
Type: "Normal",
Value: *w.state.Temperature,
})
if err != nil {
return err
}
req, err := http.NewRequest(
"POST",
"http://%s/set-temperature",
bytes.NewReader(body),
)
if err != nil {
return err
}
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
var resBody postSetTemperatureResponse
err = json.NewDecoder(res.Body).Decode(&resBody)
if err != nil || resBody.Status != "ok" {
return fmt.Errorf("refresh failed %s (bad response from query)", w.ID)
}
w.bus.RunEvent(events.HardwareState{
ID: w.ID,
InternalName: "Mill heater @ " + w.IP,
SupportFlags: device.SFlagTemperature,
State: *w.state,
})
return nil
}
type getSetTemperatureBody struct {
Type string `json:"type"`
}
type postSetTemperatureBody struct {
Type string `json:"type"`
Value float64 `json:"value"`
}
type getSetTemperatureResponse struct {
Value float64 `json:"value"`
Status string `json:"status"`
}
type postSetTemperatureResponse struct {
Status string `json:"status"`
}
Loading…
Cancel
Save