Files
new-server/cmd/bridgetest/main.go
T
Stian Fredrik Aune 88bd4dc073
continuous-integration/drone/push Build is failing
Mill. Take 1.
2021-11-07 18:38:32 +01:00

195 lines
4.9 KiB
Go
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package main
import (
"bufio"
"context"
"encoding/json"
"flag"
"fmt"
"git.aiterp.net/lucifer/new-server/app/config"
"git.aiterp.net/lucifer/new-server/models"
"log"
"os"
"sort"
"strconv"
"strings"
"time"
)
var flagDriver = flag.String("driver", string(models.DTNanoLeaf), "The bridge driver to use")
var flagAddress = flag.String("address", "127.0.0.1", "The bridge's address")
var flagToken = flag.String("token", "", "The bridge's access token / api key / login")
var flagPair = flag.Bool("pair", false, "Try to pair with the bridge.")
var flagSearch = flag.Bool("search", false, "Search for devices first.")
var flagSearchTimeout = flag.Duration("search-timeout", time.Second*3, "Timeout for device search.")
func main() {
flag.Parse()
// Find drivers
driver, err := config.DriverProvider().Provide(models.DriverKind(*flagDriver))
if err != nil {
log.Fatalln("Failed to find driver:", err)
}
// Find bridge
bridges, err := driver.SearchBridge(context.Background(), *flagAddress, *flagToken, !*flagPair)
if err != nil {
log.Fatalln("Failed to search bridge:", err)
}
if len(bridges) == 0 {
log.Fatalln("No bridges found")
}
bridge := bridges[0]
if !*flagPair {
bridge.Token = *flagToken
} else {
log.Println("New token:", bridge.Token)
}
ch := config.EventChannel
go func() {
err := driver.Run(context.Background(), bridge, ch)
if err != nil {
log.Fatalln("Run bridge stopped:", err)
}
}()
time.Sleep(time.Second)
// List devices
var devices []models.Device
if *flagSearch {
devices, err = driver.SearchDevices(context.Background(), bridge, *flagSearchTimeout)
if err != nil {
log.Fatalln("Failed to search devices:", err)
}
} else {
devices, err = driver.ListDevices(context.Background(), bridge)
if err != nil {
log.Fatalln("Failed to list devices:", err)
}
}
idMap := make(map[string]int)
nextId := len(devices) + 1
for i := range devices {
devices[i].ID = i + 1
idMap[devices[i].InternalID] = i + 1
}
go func() {
reader := bufio.NewReader(os.Stdin)
_, _ = fmt.Fprintln(os.Stderr, "Format: [id1,id2,...] [on|off] [color] [intensity]")
for _, device := range devices {
_, _ = fmt.Fprintf(os.Stderr, "Device: %d - %s %+v\n", device.ID, device.InternalID, device.Capabilities)
}
_, _ = fmt.Fprintln(os.Stderr, "Format: [id1,id2,...] [on|off] [color]")
for {
text, _ := reader.ReadString('\n')
text = strings.Trim(text, "\t  \r\n")
if text == "search" {
_, _ = driver.SearchDevices(context.Background(), bridge, time.Second)
}
if text == "list" || text == "search" || text == "json" {
devices, err = driver.ListDevices(context.Background(), bridge)
if err != nil {
log.Fatalln("Failed to list devices:", err)
}
for i, device := range devices {
if extId, ok := idMap[device.InternalID]; ok {
devices[i].ID = extId
} else {
idMap[device.InternalID] = nextId
devices[i].ID = nextId
nextId += 1
}
if text != "json" {
_, _ = fmt.Fprintf(os.Stderr, "Device: %d - %s %+v\n", device.ID, device.InternalID, device.Capabilities)
}
}
}
if text == "json" {
j, _ := json.MarshalIndent(devices, "", " ")
fmt.Println(string(j))
}
tokens := strings.Split(text, " ")
if len(tokens) < 4 {
continue
}
color, err := models.ParseColorValue(tokens[2])
if err != nil {
_, _ = fmt.Fprintln(os.Stderr, "Invalid color:", err)
continue
}
intensity, _ := strconv.ParseFloat(tokens[3], 64)
power := strings.ToLower(tokens[1]) == "on"
idsStr := strings.Split(tokens[0], ",")
ids := make([]int, 0, len(idsStr))
for _, idStr := range idsStr {
if idStr == "*" {
ids = append(ids[:0], -1)
break
}
id, err := strconv.Atoi(idStr)
if err != nil {
continue
}
ids = append(ids, id)
}
updatedDevices := devices[:0:0]
for _, device := range devices {
for _, id := range ids {
if id == -1 || id == device.ID {
if (color.IsKelvin() && device.HasCapability(models.DCColorKelvin)) || (color.IsHueSat() && device.HasCapability(models.DCColorHS)) {
device.State.Color = color
}
if device.HasCapability(models.DCPower) {
device.State.Power = power
}
if device.HasCapability(models.DCIntensity) {
device.State.Intensity = intensity
}
updatedDevices = append(updatedDevices, device)
}
}
}
if len(updatedDevices) > 0 {
err := driver.Publish(context.Background(), bridge, updatedDevices)
if err != nil {
log.Fatalln("Publish to bridge failed:", err)
return
}
}
}
}()
for event := range ch {
_, _ = fmt.Fprintf(os.Stderr, "Event %s", event.Name)
keys := make([]string, 0, 8)
for key := range event.Payload {
keys = append(keys, key)
}
sort.Strings(keys)
for _, key := range keys {
_, _ = fmt.Fprintf(os.Stderr, " %s=%#+v", key, event.Payload[key])
}
_, _ = fmt.Fprint(os.Stderr, "\n")
}
}