Author SHA1 Message Date
gisle 62e7cb88f4 refactor color system to be separate from models, also move errors out of models.
continuous-integration/drone/push Build is passing
2022-02-28 22:52:06 +01:00
gisle df865574bf rework color system and make it work with drivers.
continuous-integration/drone/push Build is passing
2022-02-21 19:27:42 +01:00
8 changed files with 14 additions and 223 deletions
+1 -1
View File
@@ -11,7 +11,7 @@ import (
func main() {
db := config.DBX().DB
log.Printf("Target version: %s", time.Now().Format("20060102150405"))
log.Printf("Target version: %s",time.Now().Format("20060102150405"))
log.Printf("Database: %s:%d/%s", config.MySqlHost(), config.MySqlPort(), config.MySqlSchema())
log.Printf("Authenticating as: %s", config.MySqlUsername())
-4
View File
@@ -36,10 +36,6 @@ EVENT HANDLER FACTORY COMMANDS
factory run <file.yaml>
MISC COMMANDS
color <color>
File example (use '---' to delimit multiple configs in one file):
mode: SceneDimmer
target: tag:Soverom
-24
View File
@@ -4,7 +4,6 @@ import (
"context"
"fmt"
"git.aiterp.net/lucifer/new-server/app/client"
"git.aiterp.net/lucifer/new-server/internal/color"
"git.aiterp.net/lucifer/new-server/models"
"log"
"os"
@@ -93,29 +92,6 @@ func main() {
WriteDeviceInfoTable(os.Stdout, devices)
}
case "color":
{
col, err := color.Parse(cmd.Params.Get(0).StringOr("hs:0,0"))
if err != nil {
log.Fatalln(err)
}
if col.IsKelvin() {
fmt.Println(col.String())
}
if hs, ok := col.ToHS(); ok {
fmt.Println(hs.String())
}
if hsk, ok := col.ToHSK(); ok {
fmt.Println(hsk.String())
}
if xy, ok := col.ToXY(); ok {
fmt.Println(xy.String())
}
if rgb, ok := col.ToRGB(); ok {
fmt.Println(rgb.String())
}
}
case "factory":
factoryCmd(ctx, c)
-18
View File
@@ -252,9 +252,6 @@ func (b *Bridge) MakeCongruent(ctx context.Context) (int, error) {
updates := make(map[string]ResourceUpdate)
for _, device := range b.devices {
resource := b.resources[device.InternalID]
if resource == nil {
continue
}
// Update device
if resource.Metadata.Name != device.Name {
@@ -622,18 +619,3 @@ func (b *Bridge) SearchDevices(ctx context.Context, timeout time.Duration) ([]mo
// Return said devices.
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 {
return errors.New("resource not found")
}
return b.client.DeleteResource(ctx, ResourceLink{
ID: device.InternalID,
Kind: "device",
})
}
-66
View File
@@ -92,10 +92,6 @@ func (c *Client) UpdateResource(ctx context.Context, link ResourceLink, update R
return c.put(ctx, link.Path(), update, nil)
}
func (c *Client) DeleteResource(ctx context.Context, link ResourceLink) error {
return c.delete(ctx, link.Path(), nil)
}
func (c *Client) LegacyDiscover(ctx context.Context, kind string) error {
return c.legacyPost(ctx, kind, nil, nil)
}
@@ -272,36 +268,6 @@ func (c *Client) post(ctx context.Context, path string, body interface{}, target
return json.NewDecoder(res.Body).Decode(&target)
}
func (c *Client) delete(ctx context.Context, path string, target interface{}) error {
select {
case <-ctx.Done():
return ctx.Err()
case <-c.ch:
defer func() {
c.ch <- struct{}{}
}()
}
req, err := http.NewRequest("PUT", fmt.Sprintf("https://%s/%s", c.host, path), nil)
if err != nil {
return err
}
req.Header.Set("hue-application-key", c.token)
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 (c *Client) legacyPost(ctx context.Context, resource string, body interface{}, target interface{}) error {
select {
case <-ctx.Done():
@@ -339,38 +305,6 @@ func (c *Client) legacyPost(ctx context.Context, resource string, body interface
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) {
if body == nil {
return nil, nil
-4
View File
@@ -100,10 +100,6 @@ func (d *Driver) Run(ctx context.Context, bridge models.Bridge, ch chan<- models
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 {
d.mu.Lock()
for _, bridge := range d.bridges {
+13 -93
View File
@@ -6,7 +6,6 @@ import (
"crypto/rand"
"crypto/sha1"
"encoding/json"
"errors"
"fmt"
"git.aiterp.net/lucifer/new-server/internal/lerrors"
"git.aiterp.net/lucifer/new-server/models"
@@ -84,16 +83,11 @@ func (b *bridge) listDevices(ctx context.Context) ([]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()
if b.luciferMillIDMap == nil {
b.luciferMillIDMap = make(map[int]int, 4)
b.millLuciferIDMap = make(map[int]int, 4)
}
subDomain := deviceModel.DriverProperties["subDomain"].(string)
if b.luciferMillIDMap[deviceModel.ID] == 0 {
millID, _ := strconv.Atoi(deviceModel.InternalID)
@@ -106,90 +100,28 @@ func (b *bridge) pushStateChange(ctx context.Context, deviceModel models.Device)
if deviceModel.State.Power {
status = 1
}
if subDomainIsGen2(subDomain) {
powerReq := deviceControlReqBody{
SubDomain: subDomain,
DeviceID: b.luciferMillIDMap[deviceModel.ID],
TestStatus: 1,
Status: status,
}
err := b.command(ctx, "deviceControl", powerReq, nil)
if err != nil {
return err
}
tempReq := changeInfoReqBody{
DeviceID: b.luciferMillIDMap[deviceModel.ID],
Value: deviceModel.State.Temperature,
TimeZoneNum: "+02:00",
Key: "holidayTemp",
}
err = b.command(ctx, "changeDeviceInfo", tempReq, nil)
if err != nil {
return err
}
} else {
sd, _ := strconv.Atoi(subDomain)
tempReq := deviceControlGen3Body{
Operation: "SINGLE_CONTROL",
Status: status,
SubDomain: sd,
DeviceId: b.luciferMillIDMap[deviceModel.ID],
HoldTemp: deviceModel.State.Temperature,
}
err := b.command(ctx, "deviceControlGen3ForApp", tempReq, nil)
if err != nil {
return err
}
powerReq := deviceControlGen3Body{
Operation: "SWITCH",
Status: status,
SubDomain: sd,
DeviceId: b.luciferMillIDMap[deviceModel.ID],
}
err = b.command(ctx, "deviceControlGen3ForApp", powerReq, nil)
if err != nil {
return err
}
powerReq := deviceControlReqBody{
SubDomain: deviceModel.DriverProperties["subDomain"].(string),
DeviceID: b.luciferMillIDMap[deviceModel.ID],
TestStatus: 1,
Status: status,
}
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,
})
err := b.command(ctx, "deviceControl", powerReq, nil)
if err != nil {
return err
}
req, err := http.NewRequestWithContext(
ctx,
"POST",
fmt.Sprintf("http://%s/set-temperature", ip),
bytes.NewReader(data),
)
tempReq := changeInfoReqBody{
DeviceID: b.luciferMillIDMap[deviceModel.ID],
Value: deviceModel.State.Temperature,
TimeZoneNum: "+02:00",
Key: "holidayTemp",
}
err = b.command(ctx, "changeDeviceInfo", tempReq, nil)
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
}
@@ -307,15 +239,3 @@ func addDefaultHeaders(req *http.Request) {
req.Header.Add("X-Zc-Seq-Id", "1")
req.Header.Add("X-Zc-Version", "1")
}
var gen2subDomains = []string{"863", "5316", "5317", "5332", "5333", "6933"}
func subDomainIsGen2(subDomain string) bool {
for _, gen2sd := range gen2subDomains {
if subDomain == gen2sd {
return true
}
}
return false
}
-13
View File
@@ -65,19 +65,6 @@ type deviceControlReqBody struct {
PowerLevel int `json:"powerLevel"`
}
type deviceControlGen3Body struct {
Operation string `json:"operation"`
Status int `json:"status"`
SubDomain int `json:"subDomain"`
DeviceId int `json:"deviceId"`
HoldTemp int `json:"holdTemp,omitempty"`
}
type wifiSetTemperatureBody struct {
Type string `json:"type"`
Value int `json:"value"`
}
var location *time.Location
func init() {