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.
285 lines
8.3 KiB
285 lines
8.3 KiB
package hue
|
|
|
|
import (
|
|
"encoding/xml"
|
|
"errors"
|
|
"strconv"
|
|
)
|
|
|
|
type GroupData struct {
|
|
Name string `json:"name"`
|
|
Lights []string `json:"lights"`
|
|
}
|
|
|
|
type DiscoveryEntry struct {
|
|
Id string `json:"id"`
|
|
InternalIPAddress string `json:"internalipaddress"`
|
|
}
|
|
|
|
type CreateUserInput struct {
|
|
DeviceType string `json:"devicetype"`
|
|
}
|
|
|
|
type CreateUserResponse struct {
|
|
Success *struct {
|
|
Username string `json:"username"`
|
|
} `json:"success"`
|
|
Error *struct {
|
|
Type int `json:"type"`
|
|
Address string `json:"address"`
|
|
Description string `json:"description"`
|
|
} `json:"error"`
|
|
}
|
|
|
|
type Overview struct {
|
|
Lights map[int]LightData `json:"lights"`
|
|
Config BridgeConfig `json:"config"`
|
|
Sensors map[int]SensorData `json:"sensors"`
|
|
}
|
|
|
|
type BridgeConfig struct {
|
|
Name string `json:"name"`
|
|
ZigbeeChannel int `json:"zigbeechannel"`
|
|
BridgeID string `json:"bridgeid"`
|
|
Mac string `json:"mac"`
|
|
DHCP bool `json:"dhcp"`
|
|
IPAddress string `json:"ipaddress"`
|
|
NetMask string `json:"netmask"`
|
|
Gateway string `json:"gateway"`
|
|
ProxyAddress string `json:"proxyaddress"`
|
|
ProxyPort int `json:"proxyport"`
|
|
UTC string `json:"UTC"`
|
|
LocalTime string `json:"localtime"`
|
|
TimeZone string `json:"timezone"`
|
|
ModelID string `json:"modelid"`
|
|
DataStoreVersion string `json:"datastoreversion"`
|
|
SWVersion string `json:"swversion"`
|
|
APIVersion string `json:"apiversion"`
|
|
LinkButton bool `json:"linkbutton"`
|
|
PortalServices bool `json:"portalservices"`
|
|
PortalConnection string `json:"portalconnection"`
|
|
FactoryNew bool `json:"factorynew"`
|
|
StarterKitID string `json:"starterkitid"`
|
|
Whitelist map[string]WhitelistEntry `json:"whitelist"`
|
|
}
|
|
|
|
type LightState struct {
|
|
On bool `json:"on"`
|
|
Bri int `json:"bri"`
|
|
Hue int `json:"hue"`
|
|
Sat int `json:"sat"`
|
|
Effect string `json:"effect"`
|
|
XY []float64 `json:"xy"`
|
|
CT int `json:"ct"`
|
|
Alert string `json:"alert"`
|
|
ColorMode string `json:"colormode"`
|
|
Mode string `json:"mode"`
|
|
Reachable bool `json:"reachable"`
|
|
}
|
|
|
|
type LightStateInput struct {
|
|
On *bool `json:"on,omitempty"`
|
|
Bri *int `json:"bri,omitempty"`
|
|
Hue *int `json:"hue,omitempty"`
|
|
Sat *int `json:"sat,omitempty"`
|
|
Effect *string `json:"effect,omitempty"`
|
|
XY *[2]float64 `json:"xy,omitempty"`
|
|
CT *int `json:"ct,omitempty"`
|
|
Alert *string `json:"alert,omitempty"`
|
|
TransitionTime *int `json:"transitiontime,omitempty"`
|
|
}
|
|
|
|
func (input *LightStateInput) Equal(other LightStateInput) bool {
|
|
if (input.On != nil) != (other.On != nil) {
|
|
return false
|
|
} else if input.On != nil && *input.On != *other.On {
|
|
return false
|
|
}
|
|
|
|
if (input.Bri != nil) != (other.Bri != nil) {
|
|
return false
|
|
} else if input.Bri != nil && *input.Bri != *other.Bri {
|
|
return false
|
|
}
|
|
|
|
if (input.Hue != nil) != (other.Hue != nil) {
|
|
return false
|
|
} else if input.Hue != nil && *input.Hue != *other.Hue {
|
|
return false
|
|
}
|
|
|
|
if (input.Sat != nil) != (other.Sat != nil) {
|
|
return false
|
|
} else if input.Sat != nil && *input.Sat != *other.Sat {
|
|
return false
|
|
}
|
|
|
|
if (input.Effect != nil) != (other.Effect != nil) {
|
|
return false
|
|
} else if input.Effect != nil && *input.Effect != *other.Effect {
|
|
return false
|
|
}
|
|
|
|
if (input.XY != nil) != (other.XY != nil) {
|
|
return false
|
|
} else if input.XY != nil && *input.XY != *other.XY {
|
|
return false
|
|
}
|
|
|
|
if (input.CT != nil) != (other.CT != nil) {
|
|
return false
|
|
} else if input.CT != nil && *input.CT != *other.CT {
|
|
return false
|
|
}
|
|
|
|
if (input.Alert != nil) != (other.Alert != nil) {
|
|
return false
|
|
} else if input.Alert != nil && *input.Alert != *other.Alert {
|
|
return false
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
type LightData struct {
|
|
State LightState `json:"state"`
|
|
Type string `json:"type"`
|
|
Name string `json:"name"`
|
|
Modelid string `json:"modelid"`
|
|
Manufacturername string `json:"manufacturername"`
|
|
Productname string `json:"productname"`
|
|
Capabilities struct {
|
|
Certified bool `json:"certified"`
|
|
Control struct {
|
|
Mindimlevel int `json:"mindimlevel"`
|
|
Maxlumen int `json:"maxlumen"`
|
|
Colorgamuttype string `json:"colorgamuttype"`
|
|
Colorgamut [][]float64 `json:"colorgamut"`
|
|
CT struct {
|
|
Min int `json:"min"`
|
|
Max int `json:"max"`
|
|
} `json:"ct"`
|
|
} `json:"control"`
|
|
Streaming struct {
|
|
Renderer bool `json:"renderer"`
|
|
Proxy bool `json:"proxy"`
|
|
} `json:"streaming"`
|
|
} `json:"capabilities"`
|
|
Config struct {
|
|
Archetype string `json:"archetype"`
|
|
Function string `json:"function"`
|
|
Direction string `json:"direction"`
|
|
Startup struct {
|
|
Mode string `json:"mode"`
|
|
Configured bool `json:"configured"`
|
|
} `json:"startup"`
|
|
} `json:"config"`
|
|
Swupdate struct {
|
|
State string `json:"state"`
|
|
Lastinstall string `json:"lastinstall"`
|
|
} `json:"swupdate"`
|
|
Uniqueid string `json:"uniqueid"`
|
|
Swversion string `json:"swversion"`
|
|
Swconfigid string `json:"swconfigid"`
|
|
Productid string `json:"productid"`
|
|
}
|
|
|
|
type SensorData struct {
|
|
State struct {
|
|
Daylight interface{} `json:"daylight"`
|
|
ButtonEvent int `json:"buttonevent"`
|
|
LastUpdated string `json:"lastupdated"`
|
|
Presence bool `json:"presence"`
|
|
Temperature int
|
|
} `json:"state"`
|
|
Config struct {
|
|
On bool `json:"on"`
|
|
Configured bool `json:"configured"`
|
|
Sunriseoffset int `json:"sunriseoffset"`
|
|
Sunsetoffset int `json:"sunsetoffset"`
|
|
} `json:"config"`
|
|
Name string `json:"name"`
|
|
Type string `json:"type"`
|
|
Modelid string `json:"modelid"`
|
|
Manufacturername string `json:"manufacturername"`
|
|
Productname string `json:"productname"`
|
|
Swversion string `json:"swversion"`
|
|
UniqueID string `json:"uniqueid"`
|
|
}
|
|
|
|
type WhitelistEntry struct {
|
|
LastUseDate string `json:"last use date"`
|
|
CreateDate string `json:"create date"`
|
|
Name string `json:"name"`
|
|
}
|
|
|
|
type BridgeDeviceInfo struct {
|
|
XMLName xml.Name `xml:"root"`
|
|
Text string `xml:",chardata"`
|
|
Xmlns string `xml:"xmlns,attr"`
|
|
SpecVersion struct {
|
|
Text string `xml:",chardata"`
|
|
Major string `xml:"major"`
|
|
Minor string `xml:"minor"`
|
|
} `xml:"specVersion"`
|
|
URLBase string `xml:"URLBase"`
|
|
Device struct {
|
|
Text string `xml:",chardata"`
|
|
DeviceType string `xml:"deviceType"`
|
|
FriendlyName string `xml:"friendlyName"`
|
|
Manufacturer string `xml:"manufacturer"`
|
|
ManufacturerURL string `xml:"manufacturerURL"`
|
|
ModelDescription string `xml:"modelDescription"`
|
|
ModelName string `xml:"modelName"`
|
|
ModelNumber string `xml:"modelNumber"`
|
|
ModelURL string `xml:"modelURL"`
|
|
SerialNumber string `xml:"serialNumber"`
|
|
UDN string `xml:"UDN"`
|
|
PresentationURL string `xml:"presentationURL"`
|
|
IconList struct {
|
|
Text string `xml:",chardata"`
|
|
Icon struct {
|
|
Text string `xml:",chardata"`
|
|
Mimetype string `xml:"mimetype"`
|
|
Height string `xml:"height"`
|
|
Width string `xml:"width"`
|
|
Depth string `xml:"depth"`
|
|
URL string `xml:"url"`
|
|
} `xml:"icon"`
|
|
} `xml:"iconList"`
|
|
} `xml:"device"`
|
|
}
|
|
|
|
type syncGroup struct {
|
|
GroupIndex int
|
|
State LightStateInput
|
|
Indexes []int
|
|
ArrayIndexes []int
|
|
}
|
|
|
|
func (sg *syncGroup) Matches(group *GroupData) bool {
|
|
if len(sg.Indexes) != len(group.Lights) {
|
|
return false
|
|
}
|
|
|
|
for _, idx := range sg.Indexes {
|
|
found := false
|
|
for _, idx2 := range group.Lights {
|
|
n := strconv.Itoa(idx)
|
|
if n == idx2 {
|
|
found = true
|
|
break
|
|
}
|
|
}
|
|
|
|
if !found {
|
|
return false
|
|
}
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
var buttonNames = []string{"On", "DimUp", "DimDown", "Off"}
|
|
|
|
var errLinkButtonNotPressed = errors.New("link button not pressed")
|