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

  1. package hue
  2. import (
  3. "encoding/xml"
  4. "errors"
  5. "strconv"
  6. )
  7. type GroupData struct {
  8. Name string `json:"name"`
  9. Lights []string `json:"lights"`
  10. }
  11. type DiscoveryEntry struct {
  12. Id string `json:"id"`
  13. InternalIPAddress string `json:"internalipaddress"`
  14. }
  15. type CreateUserInput struct {
  16. DeviceType string `json:"devicetype"`
  17. }
  18. type CreateUserResponse struct {
  19. Success *struct {
  20. Username string `json:"username"`
  21. } `json:"success"`
  22. Error *struct {
  23. Type int `json:"type"`
  24. Address string `json:"address"`
  25. Description string `json:"description"`
  26. } `json:"error"`
  27. }
  28. type Overview struct {
  29. Lights map[int]LightData `json:"lights"`
  30. Config BridgeConfig `json:"config"`
  31. Sensors map[int]SensorData `json:"sensors"`
  32. }
  33. type BridgeConfig struct {
  34. Name string `json:"name"`
  35. ZigbeeChannel int `json:"zigbeechannel"`
  36. BridgeID string `json:"bridgeid"`
  37. Mac string `json:"mac"`
  38. DHCP bool `json:"dhcp"`
  39. IPAddress string `json:"ipaddress"`
  40. NetMask string `json:"netmask"`
  41. Gateway string `json:"gateway"`
  42. ProxyAddress string `json:"proxyaddress"`
  43. ProxyPort int `json:"proxyport"`
  44. UTC string `json:"UTC"`
  45. LocalTime string `json:"localtime"`
  46. TimeZone string `json:"timezone"`
  47. ModelID string `json:"modelid"`
  48. DataStoreVersion string `json:"datastoreversion"`
  49. SWVersion string `json:"swversion"`
  50. APIVersion string `json:"apiversion"`
  51. LinkButton bool `json:"linkbutton"`
  52. PortalServices bool `json:"portalservices"`
  53. PortalConnection string `json:"portalconnection"`
  54. FactoryNew bool `json:"factorynew"`
  55. StarterKitID string `json:"starterkitid"`
  56. Whitelist map[string]WhitelistEntry `json:"whitelist"`
  57. }
  58. type LightState struct {
  59. On bool `json:"on"`
  60. Bri int `json:"bri"`
  61. Hue int `json:"hue"`
  62. Sat int `json:"sat"`
  63. Effect string `json:"effect"`
  64. XY []float64 `json:"xy"`
  65. CT int `json:"ct"`
  66. Alert string `json:"alert"`
  67. ColorMode string `json:"colormode"`
  68. Mode string `json:"mode"`
  69. Reachable bool `json:"reachable"`
  70. }
  71. type LightStateInput struct {
  72. On *bool `json:"on,omitempty"`
  73. Bri *int `json:"bri,omitempty"`
  74. Hue *int `json:"hue,omitempty"`
  75. Sat *int `json:"sat,omitempty"`
  76. Effect *string `json:"effect,omitempty"`
  77. XY *[2]float64 `json:"xy,omitempty"`
  78. CT *int `json:"ct,omitempty"`
  79. Alert *string `json:"alert,omitempty"`
  80. TransitionTime *int `json:"transitiontime,omitempty"`
  81. }
  82. func (input *LightStateInput) Equal(other LightStateInput) bool {
  83. if (input.On != nil) != (other.On != nil) {
  84. return false
  85. } else if input.On != nil && *input.On != *other.On {
  86. return false
  87. }
  88. if (input.Bri != nil) != (other.Bri != nil) {
  89. return false
  90. } else if input.Bri != nil && *input.Bri != *other.Bri {
  91. return false
  92. }
  93. if (input.Hue != nil) != (other.Hue != nil) {
  94. return false
  95. } else if input.Hue != nil && *input.Hue != *other.Hue {
  96. return false
  97. }
  98. if (input.Sat != nil) != (other.Sat != nil) {
  99. return false
  100. } else if input.Sat != nil && *input.Sat != *other.Sat {
  101. return false
  102. }
  103. if (input.Effect != nil) != (other.Effect != nil) {
  104. return false
  105. } else if input.Effect != nil && *input.Effect != *other.Effect {
  106. return false
  107. }
  108. if (input.XY != nil) != (other.XY != nil) {
  109. return false
  110. } else if input.XY != nil && *input.XY != *other.XY {
  111. return false
  112. }
  113. if (input.CT != nil) != (other.CT != nil) {
  114. return false
  115. } else if input.CT != nil && *input.CT != *other.CT {
  116. return false
  117. }
  118. if (input.Alert != nil) != (other.Alert != nil) {
  119. return false
  120. } else if input.Alert != nil && *input.Alert != *other.Alert {
  121. return false
  122. }
  123. return true
  124. }
  125. type LightData struct {
  126. State LightState `json:"state"`
  127. Type string `json:"type"`
  128. Name string `json:"name"`
  129. Modelid string `json:"modelid"`
  130. Manufacturername string `json:"manufacturername"`
  131. Productname string `json:"productname"`
  132. Capabilities struct {
  133. Certified bool `json:"certified"`
  134. Control struct {
  135. Mindimlevel int `json:"mindimlevel"`
  136. Maxlumen int `json:"maxlumen"`
  137. Colorgamuttype string `json:"colorgamuttype"`
  138. Colorgamut [][]float64 `json:"colorgamut"`
  139. CT struct {
  140. Min int `json:"min"`
  141. Max int `json:"max"`
  142. } `json:"ct"`
  143. } `json:"control"`
  144. Streaming struct {
  145. Renderer bool `json:"renderer"`
  146. Proxy bool `json:"proxy"`
  147. } `json:"streaming"`
  148. } `json:"capabilities"`
  149. Config struct {
  150. Archetype string `json:"archetype"`
  151. Function string `json:"function"`
  152. Direction string `json:"direction"`
  153. Startup struct {
  154. Mode string `json:"mode"`
  155. Configured bool `json:"configured"`
  156. } `json:"startup"`
  157. } `json:"config"`
  158. Swupdate struct {
  159. State string `json:"state"`
  160. Lastinstall string `json:"lastinstall"`
  161. } `json:"swupdate"`
  162. Uniqueid string `json:"uniqueid"`
  163. Swversion string `json:"swversion"`
  164. Swconfigid string `json:"swconfigid"`
  165. Productid string `json:"productid"`
  166. }
  167. type SensorData struct {
  168. State struct {
  169. Daylight interface{} `json:"daylight"`
  170. ButtonEvent int `json:"buttonevent"`
  171. LastUpdated string `json:"lastupdated"`
  172. Presence bool `json:"presence"`
  173. Temperature int
  174. } `json:"state"`
  175. Config struct {
  176. On bool `json:"on"`
  177. Configured bool `json:"configured"`
  178. Sunriseoffset int `json:"sunriseoffset"`
  179. Sunsetoffset int `json:"sunsetoffset"`
  180. } `json:"config"`
  181. Name string `json:"name"`
  182. Type string `json:"type"`
  183. Modelid string `json:"modelid"`
  184. Manufacturername string `json:"manufacturername"`
  185. Productname string `json:"productname"`
  186. Swversion string `json:"swversion"`
  187. UniqueID string `json:"uniqueid"`
  188. }
  189. type WhitelistEntry struct {
  190. LastUseDate string `json:"last use date"`
  191. CreateDate string `json:"create date"`
  192. Name string `json:"name"`
  193. }
  194. type BridgeDeviceInfo struct {
  195. XMLName xml.Name `xml:"root"`
  196. Text string `xml:",chardata"`
  197. Xmlns string `xml:"xmlns,attr"`
  198. SpecVersion struct {
  199. Text string `xml:",chardata"`
  200. Major string `xml:"major"`
  201. Minor string `xml:"minor"`
  202. } `xml:"specVersion"`
  203. URLBase string `xml:"URLBase"`
  204. Device struct {
  205. Text string `xml:",chardata"`
  206. DeviceType string `xml:"deviceType"`
  207. FriendlyName string `xml:"friendlyName"`
  208. Manufacturer string `xml:"manufacturer"`
  209. ManufacturerURL string `xml:"manufacturerURL"`
  210. ModelDescription string `xml:"modelDescription"`
  211. ModelName string `xml:"modelName"`
  212. ModelNumber string `xml:"modelNumber"`
  213. ModelURL string `xml:"modelURL"`
  214. SerialNumber string `xml:"serialNumber"`
  215. UDN string `xml:"UDN"`
  216. PresentationURL string `xml:"presentationURL"`
  217. IconList struct {
  218. Text string `xml:",chardata"`
  219. Icon struct {
  220. Text string `xml:",chardata"`
  221. Mimetype string `xml:"mimetype"`
  222. Height string `xml:"height"`
  223. Width string `xml:"width"`
  224. Depth string `xml:"depth"`
  225. URL string `xml:"url"`
  226. } `xml:"icon"`
  227. } `xml:"iconList"`
  228. } `xml:"device"`
  229. }
  230. type syncGroup struct {
  231. GroupIndex int
  232. State LightStateInput
  233. Indexes []int
  234. ArrayIndexes []int
  235. }
  236. func (sg *syncGroup) Matches(group *GroupData) bool {
  237. if len(sg.Indexes) != len(group.Lights) {
  238. return false
  239. }
  240. for _, idx := range sg.Indexes {
  241. found := false
  242. for _, idx2 := range group.Lights {
  243. n := strconv.Itoa(idx)
  244. if n == idx2 {
  245. found = true
  246. break
  247. }
  248. }
  249. if !found {
  250. return false
  251. }
  252. }
  253. return true
  254. }
  255. var buttonNames = []string{"On", "DimUp", "DimDown", "Off"}
  256. var errLinkButtonNotPressed = errors.New("link button not pressed")