3 Commits
Author SHA1 Message Date
gisle edb45c74b6 Merge branch 'asmodeus' of git.aiterp.net:lucifer/new-server into asmodeus
continuous-integration/drone/push Build is passing
2023-08-31 20:25:59 +02:00
gisle c4b391db66 add forgetting devices to hue2 (untested yolo-deploy). 2023-08-31 20:25:26 +02:00
Stian Fredrik Aune 3bf8cbef2f Mill option for local client
continuous-integration/drone Build is passing
continuous-integration/drone/tag Build is passing
2023-02-12 22:18:17 +01:00
5 changed files with 91 additions and 0 deletions
+11
View File
@@ -619,3 +619,14 @@ func (b *Bridge) SearchDevices(ctx context.Context, timeout time.Duration) ([]mo
// Return said devices. // Return said devices.
return newDevices, nil return newDevices, nil
} }
func (b *Bridge) Forget(ctx context.Context, device models.Device) error {
b.mu.Lock()
resource := b.resources[device.InternalID]
b.mu.Unlock()
if resource == nil || resource.LegacyID == "" {
return errors.New("resource not found")
}
return b.client.legacyDelete(ctx, resource.LegacyID, nil)
}
+32
View File
@@ -305,6 +305,38 @@ func (c *Client) legacyPost(ctx context.Context, resource string, body interface
return json.NewDecoder(res.Body).Decode(target) return json.NewDecoder(res.Body).Decode(target)
} }
func (c *Client) legacyDelete(ctx context.Context, resource string, target interface{}) error {
select {
case <-ctx.Done():
return ctx.Err()
case <-c.ch:
defer func() {
c.ch <- struct{}{}
}()
}
if c.token != "" {
resource = c.token + "/" + resource
}
req, err := http.NewRequest("DELETE", fmt.Sprintf("http://%s/api/%s", c.host, resource), nil)
if err != nil {
return err
}
res, err := httpClient.Do(req.WithContext(ctx))
if err != nil {
return err
}
defer res.Body.Close()
if target == nil {
return nil
}
return json.NewDecoder(res.Body).Decode(target)
}
func reqBody(body interface{}) (io.Reader, error) { func reqBody(body interface{}) (io.Reader, error) {
if body == nil { if body == nil {
return nil, nil return nil, nil
+4
View File
@@ -100,6 +100,10 @@ func (d *Driver) Run(ctx context.Context, bridge models.Bridge, ch chan<- models
return d.ensureBridge(bridge).Run(ctx, ch) return d.ensureBridge(bridge).Run(ctx, ch)
} }
func (d *Driver) ForgetDevice(ctx context.Context, bridge models.Bridge, device models.Device) error {
return d.ensureBridge(bridge).Forget(ctx, device)
}
func (d *Driver) ensureBridge(info models.Bridge) *Bridge { func (d *Driver) ensureBridge(info models.Bridge) *Bridge {
d.mu.Lock() d.mu.Lock()
for _, bridge := range d.bridges { for _, bridge := range d.bridges {
+39
View File
@@ -6,6 +6,7 @@ import (
"crypto/rand" "crypto/rand"
"crypto/sha1" "crypto/sha1"
"encoding/json" "encoding/json"
"errors"
"fmt" "fmt"
"git.aiterp.net/lucifer/new-server/internal/lerrors" "git.aiterp.net/lucifer/new-server/internal/lerrors"
"git.aiterp.net/lucifer/new-server/models" "git.aiterp.net/lucifer/new-server/models"
@@ -83,6 +84,10 @@ func (b *bridge) listDevices(ctx context.Context) ([]models.Device, error) {
} }
func (b *bridge) pushStateChange(ctx context.Context, deviceModel models.Device) error { func (b *bridge) pushStateChange(ctx context.Context, deviceModel models.Device) error {
if ip, ok := deviceModel.DriverProperties["ip"].(string); ok {
return b.pushWifiStateChange(ctx, ip, deviceModel.State.Temperature)
}
b.mu.Lock() b.mu.Lock()
if b.luciferMillIDMap == nil { if b.luciferMillIDMap == nil {
b.luciferMillIDMap = make(map[int]int, 4) b.luciferMillIDMap = make(map[int]int, 4)
@@ -154,6 +159,40 @@ func (b *bridge) pushStateChange(ctx context.Context, deviceModel models.Device)
return nil return nil
} }
func (b *bridge) pushWifiStateChange(ctx context.Context, ip string, temperature int) error {
b.mu.Lock()
defer b.mu.Unlock()
data, err := json.Marshal(wifiSetTemperatureBody{
Type: "Normal",
Value: temperature,
})
if err != nil {
return err
}
req, err := http.NewRequestWithContext(
ctx,
"POST",
fmt.Sprintf("http://%s/set-temperature", ip),
bytes.NewReader(data),
)
if err != nil {
return err
}
res, err := http.DefaultClient.Do(req)
if err != nil {
return err
}
if res.StatusCode > 299 {
return errors.New("mill: negative response from " + ip)
}
return nil
}
func (b *bridge) command(ctx context.Context, command string, payload interface{}, target interface{}) error { func (b *bridge) command(ctx context.Context, command string, payload interface{}, target interface{}) error {
err := b.authenticate(ctx) err := b.authenticate(ctx)
if err != nil { if err != nil {
+5
View File
@@ -73,6 +73,11 @@ type deviceControlGen3Body struct {
HoldTemp int `json:"holdTemp,omitempty"` HoldTemp int `json:"holdTemp,omitempty"`
} }
type wifiSetTemperatureBody struct {
Type string `json:"type"`
Value int `json:"value"`
}
var location *time.Location var location *time.Location
func init() { func init() {