github.com/amimof/huego@v1.2.1/bridge.go (about)

     1  package huego
     2  
     3  import (
     4  	"context"
     5  	"encoding/json"
     6  	"errors"
     7  	"fmt"
     8  	"net/url"
     9  	"path"
    10  	"strconv"
    11  	"strings"
    12  )
    13  
    14  // Bridge exposes a hardware bridge through a struct.
    15  type Bridge struct {
    16  	Host string `json:"internalipaddress,omitempty"`
    17  	User string
    18  	ID   string `json:"id,omitempty"`
    19  }
    20  
    21  func (b *Bridge) getAPIPath(str ...string) (string, error) {
    22  
    23  	if strings.Index(strings.ToLower(b.Host), "http://") <= -1 && strings.Index(strings.ToLower(b.Host), "https://") <= -1 {
    24  		b.Host = fmt.Sprintf("%s%s", "http://", b.Host)
    25  	}
    26  
    27  	u, err := url.Parse(b.Host)
    28  	if err != nil {
    29  		return "", err
    30  	}
    31  
    32  	u.Path = path.Join(u.Path, "/api/", b.User)
    33  	for _, p := range str {
    34  		u.Path = path.Join(u.Path, p)
    35  	}
    36  	return u.String(), nil
    37  }
    38  
    39  // Login calls New() and passes Host on this Bridge instance.
    40  func (b *Bridge) Login(u string) *Bridge {
    41  	b.User = u
    42  	return New(b.Host, u)
    43  }
    44  
    45  /*
    46  
    47  	CONFIGURATION API
    48  
    49  */
    50  
    51  // GetConfig returns the bridge configuration
    52  func (b *Bridge) GetConfig() (*Config, error) {
    53  	return b.GetConfigContext(context.Background())
    54  }
    55  
    56  // GetConfigContext returns the bridge configuration
    57  func (b *Bridge) GetConfigContext(ctx context.Context) (*Config, error) {
    58  
    59  	var config *Config
    60  
    61  	url, err := b.getAPIPath("/config/")
    62  	if err != nil {
    63  		return nil, err
    64  	}
    65  
    66  	res, err := get(ctx, url)
    67  	if err != nil {
    68  		return nil, err
    69  	}
    70  
    71  	err = unmarshal(res, &config)
    72  	if err != nil {
    73  		return nil, err
    74  	}
    75  
    76  	wl := make([]Whitelist, 0, len(config.WhitelistMap))
    77  	for k, v := range config.WhitelistMap {
    78  		v.Username = k
    79  		wl = append(wl, v)
    80  	}
    81  
    82  	config.Whitelist = wl
    83  
    84  	return config, nil
    85  
    86  }
    87  
    88  // CreateUser creates a user by adding n to the list of whitelists in the bridge.
    89  // The link button on the bridge must have been pressed before calling CreateUser.
    90  func (b *Bridge) CreateUser(n string) (string, error) {
    91  	return b.CreateUserContext(context.Background(), n)
    92  }
    93  
    94  // CreateUserContext creates a user by adding n to the list of whitelists in the bridge.
    95  // The link button on the bridge must have been pressed before calling CreateUser.
    96  func (b *Bridge) CreateUserContext(ctx context.Context, n string) (string, error) {
    97  	wl, err := b.createUserWithContext(ctx, n, false)
    98  	if err != nil {
    99  		return "", err
   100  	}
   101  
   102  	return wl.Username, nil
   103  }
   104  
   105  // CreateUserWithClientKey creates a user by adding deviceType to the list of whitelisted users on the bridge.
   106  // The link button on the bridge must have been pressed before calling CreateUser.
   107  func (b *Bridge) CreateUserWithClientKey(deviceType string) (*Whitelist, error) {
   108  	return b.createUserWithContext(context.Background(), deviceType, true)
   109  }
   110  
   111  // CreateUserWithClientKeyContext creates a user by adding deviceType to the list of whitelisted users on the bridge
   112  // The link button on the bridge must have been pressed before calling CreateUser.
   113  func (b *Bridge) CreateUserWithClientKeyContext(ctx context.Context, deviceType string) (*Whitelist, error) {
   114  	return b.createUserWithContext(ctx, deviceType, true)
   115  }
   116  
   117  func (b *Bridge) createUserWithContext(ctx context.Context, deviceType string, generateClientKey bool) (*Whitelist, error) {
   118  
   119  	var a []*APIResponse
   120  
   121  	body := struct {
   122  		DeviceType        string `json:"devicetype,omitempty"`
   123  		GenerateClientKey bool   `json:"generateclientkey,omitempty"`
   124  	}{deviceType, generateClientKey}
   125  
   126  	url, err := b.getAPIPath("/")
   127  	if err != nil {
   128  		return nil, err
   129  	}
   130  
   131  	data, err := json.Marshal(&body)
   132  	if err != nil {
   133  		return nil, err
   134  	}
   135  
   136  	res, err := post(ctx, url, data)
   137  	if err != nil {
   138  		return nil, err
   139  	}
   140  
   141  	err = unmarshal(res, &a)
   142  	if err != nil {
   143  		return nil, err
   144  	}
   145  
   146  	resp, err := handleResponse(a)
   147  	if err != nil {
   148  		return nil, err
   149  	}
   150  
   151  	wl := Whitelist{
   152  		Name:     deviceType,
   153  		Username: resp.Success["username"].(string),
   154  	}
   155  
   156  	if ck, ok := resp.Success["clientkey"]; ok {
   157  		wl.ClientKey = ck.(string)
   158  	} else if generateClientKey {
   159  		return nil, errors.New("no client key was returned when requested to generate")
   160  	}
   161  
   162  	return &wl, nil
   163  }
   164  
   165  // GetUsers returns a list of whitelists from the bridge
   166  func (b *Bridge) GetUsers() ([]Whitelist, error) {
   167  	c, err := b.GetConfig()
   168  	if err != nil {
   169  		return nil, err
   170  	}
   171  	return c.Whitelist, nil
   172  }
   173  
   174  // UpdateConfig updates the bridge configuration with c
   175  func (b *Bridge) UpdateConfig(c *Config) (*Response, error) {
   176  	return b.UpdateConfigContext(context.Background(), c)
   177  }
   178  
   179  // UpdateConfigContext updates the bridge configuration with c
   180  func (b *Bridge) UpdateConfigContext(ctx context.Context, c *Config) (*Response, error) {
   181  
   182  	var a []*APIResponse
   183  
   184  	url, err := b.getAPIPath("/config/")
   185  	if err != nil {
   186  		return nil, err
   187  	}
   188  
   189  	data, err := json.Marshal(&c)
   190  	if err != nil {
   191  		return nil, err
   192  	}
   193  
   194  	res, err := put(ctx, url, data)
   195  	if err != nil {
   196  		return nil, err
   197  	}
   198  
   199  	err = unmarshal(res, &a)
   200  	if err != nil {
   201  		return nil, err
   202  	}
   203  
   204  	resp, err := handleResponse(a)
   205  	if err != nil {
   206  		return nil, err
   207  	}
   208  
   209  	return resp, nil
   210  }
   211  
   212  // DeleteUser removes a whitelist item from whitelists on the bridge
   213  func (b *Bridge) DeleteUser(n string) error {
   214  	return b.DeleteUserContext(context.Background(), n)
   215  }
   216  
   217  // DeleteUserContext removes a whitelist item from whitelists on the bridge
   218  func (b *Bridge) DeleteUserContext(ctx context.Context, n string) error {
   219  
   220  	var a []*APIResponse
   221  
   222  	url, err := b.getAPIPath("/config/whitelist/", n)
   223  	if err != nil {
   224  		return err
   225  	}
   226  
   227  	res, err := delete(ctx, url)
   228  	if err != nil {
   229  		return err
   230  	}
   231  
   232  	_ = unmarshal(res, &a)
   233  
   234  	_, err = handleResponse(a)
   235  	if err != nil {
   236  		return err
   237  	}
   238  
   239  	return nil
   240  
   241  }
   242  
   243  // GetFullState returns the entire bridge configuration.
   244  func (b *Bridge) GetFullState() (map[string]interface{}, error) {
   245  	return b.GetFullStateContext(context.Background())
   246  }
   247  
   248  // GetFullStateContext returns the entire bridge configuration.
   249  func (b *Bridge) GetFullStateContext(ctx context.Context) (map[string]interface{}, error) {
   250  
   251  	var n map[string]interface{}
   252  
   253  	url, err := b.getAPIPath("/")
   254  	if err != nil {
   255  		return nil, err
   256  	}
   257  
   258  	res, err := get(ctx, url)
   259  	if err != nil {
   260  		return nil, err
   261  	}
   262  
   263  	err = unmarshal(res, &n)
   264  	if err != nil {
   265  		return nil, err
   266  	}
   267  
   268  	return n, nil
   269  }
   270  
   271  /*
   272  
   273  	GROUP API
   274  
   275  */
   276  
   277  // GetGroups returns all groups known to the bridge
   278  func (b *Bridge) GetGroups() ([]Group, error) {
   279  	return b.GetGroupsContext(context.Background())
   280  }
   281  
   282  // GetGroupsContext returns all groups known to the bridge
   283  func (b *Bridge) GetGroupsContext(ctx context.Context) ([]Group, error) {
   284  
   285  	var m map[string]Group
   286  
   287  	url, err := b.getAPIPath("/groups/")
   288  	if err != nil {
   289  		return nil, err
   290  	}
   291  
   292  	res, err := get(ctx, url)
   293  	if err != nil {
   294  		return nil, err
   295  	}
   296  
   297  	err = unmarshal(res, &m)
   298  	if err != nil {
   299  		return nil, err
   300  	}
   301  
   302  	groups := make([]Group, 0, len(m))
   303  
   304  	for i, g := range m {
   305  		g.ID, err = strconv.Atoi(i)
   306  		if err != nil {
   307  			return nil, err
   308  		}
   309  		g.bridge = b
   310  		groups = append(groups, g)
   311  	}
   312  
   313  	return groups, err
   314  
   315  }
   316  
   317  // GetGroup returns one group known to the bridge by its id
   318  func (b *Bridge) GetGroup(i int) (*Group, error) {
   319  	return b.GetGroupContext(context.Background(), i)
   320  }
   321  
   322  // GetGroupContext returns one group known to the bridge by its id
   323  func (b *Bridge) GetGroupContext(ctx context.Context, i int) (*Group, error) {
   324  
   325  	g := &Group{
   326  		ID: i,
   327  	}
   328  
   329  	url, err := b.getAPIPath("/groups/", strconv.Itoa(i))
   330  	if err != nil {
   331  		return nil, err
   332  	}
   333  
   334  	res, err := get(ctx, url)
   335  	if err != nil {
   336  		return nil, err
   337  	}
   338  
   339  	err = unmarshal(res, &g)
   340  	if err != nil {
   341  		return nil, err
   342  	}
   343  
   344  	g.bridge = b
   345  
   346  	return g, nil
   347  }
   348  
   349  // SetGroupState allows for setting the state of one group, controlling the state of all lights in that group.
   350  func (b *Bridge) SetGroupState(i int, l State) (*Response, error) {
   351  	return b.SetGroupStateContext(context.Background(), i, l)
   352  }
   353  
   354  // SetGroupStateContext allows for setting the state of one group, controlling the state of all lights in that group.
   355  func (b *Bridge) SetGroupStateContext(ctx context.Context, i int, l State) (*Response, error) {
   356  
   357  	var a []*APIResponse
   358  
   359  	id := strconv.Itoa(i)
   360  	url, err := b.getAPIPath("/groups/", id, "/action/")
   361  	if err != nil {
   362  		return nil, err
   363  	}
   364  
   365  	data, err := json.Marshal(&l)
   366  	if err != nil {
   367  		return nil, err
   368  	}
   369  
   370  	res, err := put(ctx, url, data)
   371  	if err != nil {
   372  		return nil, err
   373  	}
   374  
   375  	err = unmarshal(res, &a)
   376  	if err != nil {
   377  		return nil, err
   378  	}
   379  
   380  	resp, err := handleResponse(a)
   381  	if err != nil {
   382  		return nil, err
   383  	}
   384  
   385  	return resp, nil
   386  }
   387  
   388  // UpdateGroup updates one group known to the bridge
   389  func (b *Bridge) UpdateGroup(i int, l Group) (*Response, error) {
   390  	return b.UpdateGroupContext(context.Background(), i, l)
   391  }
   392  
   393  // UpdateGroupContext updates one group known to the bridge
   394  func (b *Bridge) UpdateGroupContext(ctx context.Context, i int, l Group) (*Response, error) {
   395  
   396  	var a []*APIResponse
   397  
   398  	id := strconv.Itoa(i)
   399  	url, err := b.getAPIPath("/groups/", id)
   400  	if err != nil {
   401  		return nil, err
   402  	}
   403  
   404  	data, err := json.Marshal(&l)
   405  	if err != nil {
   406  		return nil, err
   407  	}
   408  
   409  	res, err := put(ctx, url, data)
   410  	if err != nil {
   411  		return nil, err
   412  	}
   413  
   414  	err = unmarshal(res, &a)
   415  	if err != nil {
   416  		return nil, err
   417  	}
   418  
   419  	resp, err := handleResponse(a)
   420  	if err != nil {
   421  		return nil, err
   422  	}
   423  
   424  	return resp, nil
   425  }
   426  
   427  // CreateGroup creates one new group with attributes defined by g
   428  func (b *Bridge) CreateGroup(g Group) (*Response, error) {
   429  	return b.CreateGroupContext(context.Background(), g)
   430  }
   431  
   432  // CreateGroupContext creates one new group with attributes defined by g
   433  func (b *Bridge) CreateGroupContext(ctx context.Context, g Group) (*Response, error) {
   434  
   435  	var a []*APIResponse
   436  
   437  	url, err := b.getAPIPath("/groups/")
   438  	if err != nil {
   439  		return nil, err
   440  	}
   441  
   442  	data, err := json.Marshal(&g)
   443  	if err != nil {
   444  		return nil, err
   445  	}
   446  
   447  	res, err := post(ctx, url, data)
   448  	if err != nil {
   449  		return nil, err
   450  	}
   451  
   452  	err = unmarshal(res, &a)
   453  	if err != nil {
   454  		return nil, err
   455  	}
   456  
   457  	resp, err := handleResponse(a)
   458  	if err != nil {
   459  		return nil, err
   460  	}
   461  
   462  	return resp, nil
   463  }
   464  
   465  // DeleteGroup deletes one group with the id of i
   466  func (b *Bridge) DeleteGroup(i int) error {
   467  	return b.DeleteGroupContext(context.Background(), i)
   468  }
   469  
   470  // DeleteGroupContext deletes one group with the id of i
   471  func (b *Bridge) DeleteGroupContext(ctx context.Context, i int) error {
   472  
   473  	var a []*APIResponse
   474  
   475  	id := strconv.Itoa(i)
   476  	url, err := b.getAPIPath("/groups/", id)
   477  	if err != nil {
   478  		return err
   479  	}
   480  
   481  	res, err := delete(ctx, url)
   482  	if err != nil {
   483  		return err
   484  	}
   485  
   486  	_ = unmarshal(res, &a)
   487  
   488  	_, err = handleResponse(a)
   489  	if err != nil {
   490  		return err
   491  	}
   492  
   493  	return nil
   494  }
   495  
   496  /*
   497  
   498  	LIGHT API
   499  
   500  */
   501  
   502  // GetLights returns all lights known to the bridge
   503  func (b *Bridge) GetLights() ([]Light, error) {
   504  	return b.GetLightsContext(context.Background())
   505  }
   506  
   507  // GetLightsContext returns all lights known to the bridge
   508  func (b *Bridge) GetLightsContext(ctx context.Context) ([]Light, error) {
   509  
   510  	m := map[string]Light{}
   511  
   512  	url, err := b.getAPIPath("/lights/")
   513  	if err != nil {
   514  		return nil, err
   515  	}
   516  
   517  	res, err := get(ctx, url)
   518  	if err != nil {
   519  		return nil, err
   520  	}
   521  
   522  	err = unmarshal(res, &m)
   523  	if err != nil {
   524  		return nil, err
   525  	}
   526  
   527  	lights := make([]Light, 0, len(m))
   528  
   529  	for i, l := range m {
   530  		l.ID, err = strconv.Atoi(i)
   531  		if err != nil {
   532  			return nil, err
   533  		}
   534  		l.bridge = b
   535  		lights = append(lights, l)
   536  	}
   537  
   538  	return lights, nil
   539  
   540  }
   541  
   542  // GetLight returns one light with the id of i
   543  func (b *Bridge) GetLight(i int) (*Light, error) {
   544  	return b.GetLightContext(context.Background(), i)
   545  }
   546  
   547  // GetLightContext returns one light with the id of i
   548  func (b *Bridge) GetLightContext(ctx context.Context, i int) (*Light, error) {
   549  
   550  	light := &Light{
   551  		ID: i,
   552  	}
   553  
   554  	url, err := b.getAPIPath("/lights/", strconv.Itoa(i))
   555  	if err != nil {
   556  		return nil, err
   557  	}
   558  
   559  	res, err := get(ctx, url)
   560  	if err != nil {
   561  		return light, err
   562  	}
   563  
   564  	err = unmarshal(res, &light)
   565  	if err != nil {
   566  		return light, err
   567  	}
   568  
   569  	light.bridge = b
   570  
   571  	return light, nil
   572  }
   573  
   574  // IdentifyLight allows identifying a light
   575  func (b *Bridge) IdentifyLight(i int) (*Response, error) {
   576  	return b.IdentifyLightContext(context.Background(), i)
   577  }
   578  
   579  // IdentifyLightContext allows identifying a light
   580  func (b *Bridge) IdentifyLightContext(ctx context.Context, i int) (*Response, error) {
   581  
   582  	var a []*APIResponse
   583  
   584  	url, err := b.getAPIPath("/lights/", strconv.Itoa(i), "/state")
   585  	if err != nil {
   586  		return nil, err
   587  	}
   588  	res, err := put(ctx, url, []byte(`{"alert":"select"}`))
   589  	if err != nil {
   590  		return nil, err
   591  	}
   592  
   593  	err = unmarshal(res, &a)
   594  	if err != nil {
   595  		return nil, err
   596  	}
   597  
   598  	resp, err := handleResponse(a)
   599  	if err != nil {
   600  		return nil, err
   601  	}
   602  
   603  	return resp, nil
   604  
   605  }
   606  
   607  // SetLightState allows for controlling one light's state
   608  func (b *Bridge) SetLightState(i int, l State) (*Response, error) {
   609  	return b.SetLightStateContext(context.Background(), i, l)
   610  }
   611  
   612  // SetLightStateContext allows for controlling one light's state
   613  func (b *Bridge) SetLightStateContext(ctx context.Context, i int, l State) (*Response, error) {
   614  
   615  	var a []*APIResponse
   616  
   617  	l.Reachable = false
   618  	l.ColorMode = ""
   619  
   620  	data, err := json.Marshal(&l)
   621  	if err != nil {
   622  		return nil, err
   623  	}
   624  
   625  	url, err := b.getAPIPath("/lights/", strconv.Itoa(i), "/state")
   626  	if err != nil {
   627  		return nil, err
   628  	}
   629  	res, err := put(ctx, url, data)
   630  	if err != nil {
   631  		return nil, err
   632  	}
   633  
   634  	err = unmarshal(res, &a)
   635  	if err != nil {
   636  		return nil, err
   637  	}
   638  
   639  	resp, err := handleResponse(a)
   640  	if err != nil {
   641  		return nil, err
   642  	}
   643  
   644  	return resp, nil
   645  
   646  }
   647  
   648  // FindLights starts a search for new lights on the bridge.
   649  // Use GetNewLights() verify if new lights have been detected.
   650  func (b *Bridge) FindLights() (*Response, error) {
   651  	return b.FindLightsContext(context.Background())
   652  }
   653  
   654  // FindLightsContext starts a search for new lights on the bridge.
   655  // Use GetNewLights() verify if new lights have been detected.
   656  func (b *Bridge) FindLightsContext(ctx context.Context) (*Response, error) {
   657  
   658  	var a []*APIResponse
   659  
   660  	url, err := b.getAPIPath("/lights/")
   661  	if err != nil {
   662  		return nil, err
   663  	}
   664  
   665  	res, err := post(ctx, url, nil)
   666  	if err != nil {
   667  		return nil, err
   668  	}
   669  
   670  	err = unmarshal(res, &a)
   671  	if err != nil {
   672  		return nil, err
   673  	}
   674  
   675  	resp, err := handleResponse(a)
   676  	if err != nil {
   677  		return nil, err
   678  	}
   679  
   680  	return resp, nil
   681  
   682  }
   683  
   684  // GetNewLights returns a list of lights that were discovered last time FindLights() was executed.
   685  func (b *Bridge) GetNewLights() (*NewLight, error) {
   686  	return b.GetNewLightsContext(context.Background())
   687  }
   688  
   689  // GetNewLightsContext returns a list of lights that were discovered last time FindLights() was executed.
   690  func (b *Bridge) GetNewLightsContext(ctx context.Context) (*NewLight, error) {
   691  
   692  	var n map[string]interface{}
   693  
   694  	url, err := b.getAPIPath("/lights/new")
   695  	if err != nil {
   696  		return nil, err
   697  	}
   698  
   699  	res, err := get(ctx, url)
   700  	if err != nil {
   701  		return nil, err
   702  	}
   703  
   704  	_ = unmarshal(res, &n)
   705  
   706  	lights := make([]string, 0, len(n))
   707  	var lastscan string
   708  
   709  	for k := range n {
   710  		if k == "lastscan" {
   711  			lastscan = n[k].(string)
   712  		} else {
   713  			lights = append(lights, k)
   714  		}
   715  	}
   716  
   717  	result := &NewLight{
   718  		Lights:   lights,
   719  		LastScan: lastscan,
   720  	}
   721  
   722  	return result, nil
   723  
   724  }
   725  
   726  // DeleteLight deletes one lights from the bridge
   727  func (b *Bridge) DeleteLight(i int) error {
   728  	return b.DeleteLightContext(context.Background(), i)
   729  }
   730  
   731  // DeleteLightContext deletes one lights from the bridge
   732  func (b *Bridge) DeleteLightContext(ctx context.Context, i int) error {
   733  
   734  	var a []*APIResponse
   735  
   736  	id := strconv.Itoa(i)
   737  	url, err := b.getAPIPath("/lights/", id)
   738  	if err != nil {
   739  		return err
   740  	}
   741  
   742  	res, err := delete(ctx, url)
   743  	if err != nil {
   744  		return err
   745  	}
   746  
   747  	_ = unmarshal(res, &a)
   748  
   749  	_, err = handleResponse(a)
   750  	if err != nil {
   751  		return err
   752  	}
   753  
   754  	return nil
   755  
   756  }
   757  
   758  // UpdateLight updates one light's attributes and state properties
   759  func (b *Bridge) UpdateLight(i int, light Light) (*Response, error) {
   760  	return b.UpdateLightContext(context.Background(), i, light)
   761  }
   762  
   763  // UpdateLightContext updates one light's attributes and state properties
   764  func (b *Bridge) UpdateLightContext(ctx context.Context, i int, light Light) (*Response, error) {
   765  
   766  	var a []*APIResponse
   767  
   768  	id := strconv.Itoa(i)
   769  	url, err := b.getAPIPath("/lights/", id)
   770  	if err != nil {
   771  		return nil, err
   772  	}
   773  
   774  	data, err := json.Marshal(&light)
   775  	if err != nil {
   776  		return nil, err
   777  	}
   778  
   779  	res, err := put(ctx, url, data)
   780  	if err != nil {
   781  		return nil, err
   782  	}
   783  
   784  	err = unmarshal(res, &a)
   785  	if err != nil {
   786  		return nil, err
   787  	}
   788  
   789  	resp, err := handleResponse(a)
   790  	if err != nil {
   791  		return nil, err
   792  	}
   793  
   794  	return resp, nil
   795  }
   796  
   797  /*
   798  
   799  	RESOURCELINK API
   800  
   801  */
   802  
   803  // GetResourcelinks returns all resourcelinks known to the bridge
   804  func (b *Bridge) GetResourcelinks() ([]*Resourcelink, error) {
   805  	return b.GetResourcelinksContext(context.Background())
   806  }
   807  
   808  // GetResourcelinksContext returns all resourcelinks known to the bridge
   809  func (b *Bridge) GetResourcelinksContext(ctx context.Context) ([]*Resourcelink, error) {
   810  
   811  	var r map[string]Resourcelink
   812  
   813  	url, err := b.getAPIPath("/resourcelinks/")
   814  	if err != nil {
   815  		return nil, err
   816  	}
   817  
   818  	res, err := get(ctx, url)
   819  	if err != nil {
   820  		return nil, err
   821  	}
   822  
   823  	err = unmarshal(res, &r)
   824  	if err != nil {
   825  		return nil, err
   826  	}
   827  
   828  	resourcelinks := make([]*Resourcelink, 0, len(r))
   829  
   830  	for i, s := range r {
   831  		s.ID, err = strconv.Atoi(i)
   832  		if err != nil {
   833  			return nil, err
   834  		}
   835  		sCopy := s
   836  		resourcelinks = append(resourcelinks, &sCopy)
   837  	}
   838  
   839  	return resourcelinks, nil
   840  
   841  }
   842  
   843  // GetResourcelink returns one resourcelink by its id defined by i
   844  func (b *Bridge) GetResourcelink(i int) (*Resourcelink, error) {
   845  	return b.GetResourcelinkContext(context.Background(), i)
   846  }
   847  
   848  // GetResourcelinkContext returns one resourcelink by its id defined by i
   849  func (b *Bridge) GetResourcelinkContext(ctx context.Context, i int) (*Resourcelink, error) {
   850  
   851  	g := &Resourcelink{
   852  		ID: i,
   853  	}
   854  
   855  	url, err := b.getAPIPath("/resourcelinks/", strconv.Itoa(i))
   856  	if err != nil {
   857  		return nil, err
   858  	}
   859  
   860  	res, err := get(ctx, url)
   861  	if err != nil {
   862  		return nil, err
   863  	}
   864  
   865  	err = unmarshal(res, &g)
   866  	if err != nil {
   867  		return nil, err
   868  	}
   869  
   870  	return g, nil
   871  
   872  }
   873  
   874  // CreateResourcelink creates one new resourcelink on the bridge
   875  func (b *Bridge) CreateResourcelink(s *Resourcelink) (*Response, error) {
   876  	return b.CreateResourcelinkContext(context.Background(), s)
   877  }
   878  
   879  // CreateResourcelinkContext creates one new resourcelink on the bridge
   880  func (b *Bridge) CreateResourcelinkContext(ctx context.Context, s *Resourcelink) (*Response, error) {
   881  
   882  	var a []*APIResponse
   883  
   884  	data, err := json.Marshal(&s)
   885  	if err != nil {
   886  		return nil, err
   887  	}
   888  
   889  	url, err := b.getAPIPath("/resourcelinks/")
   890  	if err != nil {
   891  		return nil, err
   892  	}
   893  
   894  	res, err := post(ctx, url, data)
   895  	if err != nil {
   896  		return nil, err
   897  	}
   898  
   899  	err = unmarshal(res, &a)
   900  	if err != nil {
   901  		return nil, err
   902  	}
   903  
   904  	resp, err := handleResponse(a)
   905  	if err != nil {
   906  		return nil, err
   907  	}
   908  
   909  	return resp, nil
   910  
   911  }
   912  
   913  // UpdateResourcelink updates one resourcelink with attributes defined by resourcelink
   914  func (b *Bridge) UpdateResourcelink(i int, resourcelink *Resourcelink) (*Response, error) {
   915  	return b.UpdateResourcelinkContext(context.Background(), i, resourcelink)
   916  }
   917  
   918  // UpdateResourcelinkContext updates one resourcelink with attributes defined by resourcelink
   919  func (b *Bridge) UpdateResourcelinkContext(ctx context.Context, i int, resourcelink *Resourcelink) (*Response, error) {
   920  	var a []*APIResponse
   921  
   922  	data, err := json.Marshal(&resourcelink)
   923  	if err != nil {
   924  		return nil, err
   925  	}
   926  
   927  	url, err := b.getAPIPath("/resourcelinks/", strconv.Itoa(i))
   928  	if err != nil {
   929  		return nil, err
   930  	}
   931  
   932  	res, err := put(ctx, url, data)
   933  	if err != nil {
   934  		return nil, err
   935  	}
   936  
   937  	err = unmarshal(res, &a)
   938  	if err != nil {
   939  		return nil, err
   940  	}
   941  
   942  	resp, err := handleResponse(a)
   943  	if err != nil {
   944  		return nil, err
   945  	}
   946  
   947  	return resp, nil
   948  }
   949  
   950  // DeleteResourcelink deletes one resourcelink with the id of i
   951  func (b *Bridge) DeleteResourcelink(i int) error {
   952  	return b.DeleteResourcelinkContext(context.Background(), i)
   953  }
   954  
   955  // DeleteResourcelinkContext deletes one resourcelink with the id of i
   956  func (b *Bridge) DeleteResourcelinkContext(ctx context.Context, i int) error {
   957  
   958  	var a []*APIResponse
   959  
   960  	id := strconv.Itoa(i)
   961  	url, err := b.getAPIPath("/resourcelinks/", id)
   962  	if err != nil {
   963  		return err
   964  	}
   965  
   966  	res, err := delete(ctx, url)
   967  	if err != nil {
   968  		return err
   969  	}
   970  
   971  	_ = unmarshal(res, &a)
   972  
   973  	_, err = handleResponse(a)
   974  	if err != nil {
   975  		return err
   976  	}
   977  
   978  	return nil
   979  }
   980  
   981  /*
   982  
   983  	RULE API
   984  
   985  */
   986  
   987  // GetRules returns all rules known to the bridge
   988  func (b *Bridge) GetRules() ([]*Rule, error) {
   989  	return b.GetRulesContext(context.Background())
   990  }
   991  
   992  // GetRulesContext returns all rules known to the bridge
   993  func (b *Bridge) GetRulesContext(ctx context.Context) ([]*Rule, error) {
   994  
   995  	var r map[string]Rule
   996  
   997  	url, err := b.getAPIPath("/rules/")
   998  	if err != nil {
   999  		return nil, err
  1000  	}
  1001  
  1002  	res, err := get(ctx, url)
  1003  	if err != nil {
  1004  		return nil, err
  1005  	}
  1006  
  1007  	err = unmarshal(res, &r)
  1008  	if err != nil {
  1009  		return nil, err
  1010  	}
  1011  
  1012  	rules := make([]*Rule, 0, len(r))
  1013  
  1014  	for i, s := range r {
  1015  		s.ID, err = strconv.Atoi(i)
  1016  		if err != nil {
  1017  			return nil, err
  1018  		}
  1019  		sCopy := s
  1020  		rules = append(rules, &sCopy)
  1021  	}
  1022  
  1023  	return rules, nil
  1024  
  1025  }
  1026  
  1027  // GetRule returns one rule by its id of i
  1028  func (b *Bridge) GetRule(i int) (*Rule, error) {
  1029  	return b.GetRuleContext(context.Background(), i)
  1030  }
  1031  
  1032  // GetRuleContext returns one rule by its id of i
  1033  func (b *Bridge) GetRuleContext(ctx context.Context, i int) (*Rule, error) {
  1034  
  1035  	g := &Rule{
  1036  		ID: i,
  1037  	}
  1038  
  1039  	url, err := b.getAPIPath("/rules/", strconv.Itoa(i))
  1040  	if err != nil {
  1041  		return nil, err
  1042  	}
  1043  
  1044  	res, err := get(ctx, url)
  1045  	if err != nil {
  1046  		return nil, err
  1047  	}
  1048  
  1049  	err = unmarshal(res, &g)
  1050  	if err != nil {
  1051  		return nil, err
  1052  	}
  1053  
  1054  	return g, nil
  1055  
  1056  }
  1057  
  1058  // CreateRule creates one rule with attribues defined in s
  1059  func (b *Bridge) CreateRule(s *Rule) (*Response, error) {
  1060  	return b.CreateRuleContext(context.Background(), s)
  1061  }
  1062  
  1063  // CreateRuleContext creates one rule with attribues defined in s
  1064  func (b *Bridge) CreateRuleContext(ctx context.Context, s *Rule) (*Response, error) {
  1065  
  1066  	var a []*APIResponse
  1067  
  1068  	data, err := json.Marshal(&s)
  1069  	if err != nil {
  1070  		return nil, err
  1071  	}
  1072  
  1073  	url, err := b.getAPIPath("/rules/")
  1074  	if err != nil {
  1075  		return nil, err
  1076  	}
  1077  
  1078  	res, err := post(ctx, url, data)
  1079  	if err != nil {
  1080  		return nil, err
  1081  	}
  1082  
  1083  	err = unmarshal(res, &a)
  1084  	if err != nil {
  1085  		return nil, err
  1086  	}
  1087  
  1088  	resp, err := handleResponse(a)
  1089  	if err != nil {
  1090  		return nil, err
  1091  	}
  1092  
  1093  	return resp, nil
  1094  
  1095  }
  1096  
  1097  // UpdateRule updates one rule by its id of i and rule configuration of rule
  1098  func (b *Bridge) UpdateRule(i int, rule *Rule) (*Response, error) {
  1099  	return b.UpdateRuleContext(context.Background(), i, rule)
  1100  }
  1101  
  1102  // UpdateRuleContext updates one rule by its id of i and rule configuration of rule
  1103  func (b *Bridge) UpdateRuleContext(ctx context.Context, i int, rule *Rule) (*Response, error) {
  1104  
  1105  	var a []*APIResponse
  1106  
  1107  	data, err := json.Marshal(&rule)
  1108  	if err != nil {
  1109  		return nil, err
  1110  	}
  1111  
  1112  	url, err := b.getAPIPath("/rules/", strconv.Itoa(i))
  1113  	if err != nil {
  1114  		return nil, err
  1115  	}
  1116  
  1117  	res, err := put(ctx, url, data)
  1118  	if err != nil {
  1119  		return nil, err
  1120  	}
  1121  
  1122  	err = unmarshal(res, &a)
  1123  	if err != nil {
  1124  		return nil, err
  1125  	}
  1126  
  1127  	resp, err := handleResponse(a)
  1128  	if err != nil {
  1129  		return nil, err
  1130  	}
  1131  
  1132  	return resp, nil
  1133  }
  1134  
  1135  // DeleteRule deletes one rule from the bridge
  1136  func (b *Bridge) DeleteRule(i int) error {
  1137  	return b.DeleteRuleContext(context.Background(), i)
  1138  }
  1139  
  1140  // DeleteRuleContext deletes one rule from the bridge
  1141  func (b *Bridge) DeleteRuleContext(ctx context.Context, i int) error {
  1142  
  1143  	var a []*APIResponse
  1144  
  1145  	id := strconv.Itoa(i)
  1146  	url, err := b.getAPIPath("/rules/", id)
  1147  	if err != nil {
  1148  		return err
  1149  	}
  1150  
  1151  	res, err := delete(ctx, url)
  1152  	if err != nil {
  1153  		return err
  1154  	}
  1155  
  1156  	_ = unmarshal(res, &a)
  1157  
  1158  	_, err = handleResponse(a)
  1159  	if err != nil {
  1160  		return err
  1161  	}
  1162  
  1163  	return nil
  1164  }
  1165  
  1166  /*
  1167  
  1168  	SCENE API
  1169  
  1170  */
  1171  
  1172  // GetScenes returns all scenes known to the bridge
  1173  func (b *Bridge) GetScenes() ([]Scene, error) {
  1174  	return b.GetScenesContext(context.Background())
  1175  }
  1176  
  1177  // GetScenesContext returns all scenes known to the bridge
  1178  func (b *Bridge) GetScenesContext(ctx context.Context) ([]Scene, error) {
  1179  
  1180  	var m map[string]Scene
  1181  
  1182  	url, err := b.getAPIPath("/scenes/")
  1183  	if err != nil {
  1184  		return nil, err
  1185  	}
  1186  
  1187  	res, err := get(ctx, url)
  1188  	if err != nil {
  1189  		return nil, err
  1190  	}
  1191  
  1192  	err = unmarshal(res, &m)
  1193  	scenes := make([]Scene, 0, len(m))
  1194  
  1195  	for i, g := range m {
  1196  		g.ID = i
  1197  		g.bridge = b
  1198  		scenes = append(scenes, g)
  1199  	}
  1200  
  1201  	return scenes, err
  1202  
  1203  }
  1204  
  1205  // GetScene returns one scene by its id of i
  1206  func (b *Bridge) GetScene(i string) (*Scene, error) {
  1207  	return b.GetSceneContext(context.Background(), i)
  1208  }
  1209  
  1210  // GetSceneContext returns one scene by its id of i
  1211  func (b *Bridge) GetSceneContext(ctx context.Context, i string) (*Scene, error) {
  1212  
  1213  	g := &Scene{ID: i}
  1214  	l := struct {
  1215  		LightStates map[int]State `json:"lightstates"`
  1216  	}{}
  1217  
  1218  	url, err := b.getAPIPath("/scenes/", i)
  1219  	if err != nil {
  1220  		return nil, err
  1221  	}
  1222  
  1223  	res, err := get(ctx, url)
  1224  	if err != nil {
  1225  		return nil, err
  1226  	}
  1227  
  1228  	err = unmarshal(res, &l)
  1229  	if err != nil {
  1230  		return nil, err
  1231  	}
  1232  
  1233  	err = unmarshal(res, &g)
  1234  	if err != nil {
  1235  		return nil, err
  1236  	}
  1237  
  1238  	g.bridge = b
  1239  
  1240  	return g, nil
  1241  }
  1242  
  1243  // UpdateScene updates one scene and its attributes by id of i
  1244  func (b *Bridge) UpdateScene(id string, s *Scene) (*Response, error) {
  1245  	return b.UpdateSceneContext(context.Background(), id, s)
  1246  }
  1247  
  1248  // UpdateSceneContext updates one scene and its attributes by id of i
  1249  func (b *Bridge) UpdateSceneContext(ctx context.Context, id string, s *Scene) (*Response, error) {
  1250  
  1251  	var a []*APIResponse
  1252  
  1253  	url, err := b.getAPIPath("/scenes/", id)
  1254  	if err != nil {
  1255  		return nil, err
  1256  	}
  1257  
  1258  	data, err := json.Marshal(&s)
  1259  	if err != nil {
  1260  		return nil, err
  1261  	}
  1262  
  1263  	res, err := put(ctx, url, data)
  1264  	if err != nil {
  1265  		return nil, err
  1266  	}
  1267  
  1268  	err = unmarshal(res, &a)
  1269  	if err != nil {
  1270  		return nil, err
  1271  	}
  1272  
  1273  	resp, err := handleResponse(a)
  1274  	if err != nil {
  1275  		return nil, err
  1276  	}
  1277  
  1278  	return resp, nil
  1279  }
  1280  
  1281  // SetSceneLightState allows for setting the state of a light in a scene.
  1282  // SetSceneLightState accepts the id of the scene, the id of a light associated with the scene and the state object.
  1283  func (b *Bridge) SetSceneLightState(id string, iid int, l *State) (*Response, error) {
  1284  	return b.SetSceneLightStateContext(context.Background(), id, iid, l)
  1285  }
  1286  
  1287  // SetSceneLightStateContext allows for setting the state of a light in a scene.
  1288  // SetSceneLightStateContext accepts the id of the scene, the id of a light associated with the scene and the state object.
  1289  func (b *Bridge) SetSceneLightStateContext(ctx context.Context, id string, iid int, l *State) (*Response, error) {
  1290  
  1291  	var a []*APIResponse
  1292  
  1293  	lightid := strconv.Itoa(iid)
  1294  	url, err := b.getAPIPath("scenes", id, "lightstates", lightid)
  1295  	if err != nil {
  1296  		return nil, err
  1297  	}
  1298  
  1299  	data, err := json.Marshal(&l)
  1300  	if err != nil {
  1301  		return nil, err
  1302  	}
  1303  
  1304  	res, err := put(ctx, url, data)
  1305  	if err != nil {
  1306  		return nil, err
  1307  	}
  1308  
  1309  	err = unmarshal(res, &a)
  1310  	if err != nil {
  1311  		return nil, err
  1312  	}
  1313  
  1314  	resp, err := handleResponse(a)
  1315  	if err != nil {
  1316  		return nil, err
  1317  	}
  1318  
  1319  	return resp, nil
  1320  }
  1321  
  1322  // RecallScene will recall a scene in a group identified by both scene and group identifiers
  1323  func (b *Bridge) RecallScene(id string, gid int) (*Response, error) {
  1324  	return b.RecallSceneContext(context.Background(), id, gid)
  1325  }
  1326  
  1327  // RecallSceneContext will recall a scene in a group identified by both scene and group identifiers
  1328  func (b *Bridge) RecallSceneContext(ctx context.Context, id string, gid int) (*Response, error) {
  1329  
  1330  	var a []*APIResponse
  1331  
  1332  	data, err := json.Marshal(struct {
  1333  		Scene string `json:"scene"`
  1334  	}{id})
  1335  
  1336  	if err != nil {
  1337  		return nil, err
  1338  	}
  1339  
  1340  	url, err := b.getAPIPath("/groups/", strconv.Itoa(gid), "/action")
  1341  	if err != nil {
  1342  		return nil, err
  1343  	}
  1344  
  1345  	res, err := put(ctx, url, data)
  1346  	if err != nil {
  1347  		return nil, err
  1348  	}
  1349  
  1350  	err = unmarshal(res, &a)
  1351  	if err != nil {
  1352  		return nil, err
  1353  	}
  1354  
  1355  	resp, err := handleResponse(a)
  1356  	if err != nil {
  1357  		return nil, err
  1358  	}
  1359  
  1360  	return resp, err
  1361  }
  1362  
  1363  // CreateScene creates one new scene with its attributes defined in s
  1364  func (b *Bridge) CreateScene(s *Scene) (*Response, error) {
  1365  	return b.CreateSceneContext(context.Background(), s)
  1366  }
  1367  
  1368  // CreateSceneContext creates one new scene with its attributes defined in s
  1369  func (b *Bridge) CreateSceneContext(ctx context.Context, s *Scene) (*Response, error) {
  1370  
  1371  	var a []*APIResponse
  1372  
  1373  	data, err := json.Marshal(&s)
  1374  	if err != nil {
  1375  		return nil, err
  1376  	}
  1377  
  1378  	url, err := b.getAPIPath("/scenes/")
  1379  	if err != nil {
  1380  		return nil, err
  1381  	}
  1382  
  1383  	res, err := post(ctx, url, data)
  1384  	if err != nil {
  1385  		return nil, err
  1386  	}
  1387  
  1388  	err = unmarshal(res, &a)
  1389  	if err != nil {
  1390  		return nil, err
  1391  	}
  1392  
  1393  	resp, err := handleResponse(a)
  1394  	if err != nil {
  1395  		return nil, err
  1396  	}
  1397  
  1398  	return resp, nil
  1399  }
  1400  
  1401  // DeleteScene deletes one scene from the bridge
  1402  func (b *Bridge) DeleteScene(id string) error {
  1403  	return b.DeleteSceneContext(context.Background(), id)
  1404  }
  1405  
  1406  // DeleteSceneContext deletes one scene from the bridge
  1407  func (b *Bridge) DeleteSceneContext(ctx context.Context, id string) error {
  1408  
  1409  	var a []*APIResponse
  1410  
  1411  	url, err := b.getAPIPath("/scenes/", id)
  1412  	if err != nil {
  1413  		return err
  1414  	}
  1415  
  1416  	res, err := delete(ctx, url)
  1417  	if err != nil {
  1418  		return err
  1419  	}
  1420  
  1421  	_ = unmarshal(res, &a)
  1422  
  1423  	_, err = handleResponse(a)
  1424  	if err != nil {
  1425  		return err
  1426  	}
  1427  
  1428  	return nil
  1429  }
  1430  
  1431  /*
  1432  
  1433  	SCHEDULE API
  1434  
  1435  */
  1436  
  1437  // GetSchedules returns all schedules known to the bridge
  1438  func (b *Bridge) GetSchedules() ([]*Schedule, error) {
  1439  	return b.GetSchedulesContext(context.Background())
  1440  }
  1441  
  1442  // GetSchedulesContext returns all schedules known to the bridge
  1443  func (b *Bridge) GetSchedulesContext(ctx context.Context) ([]*Schedule, error) {
  1444  
  1445  	var r map[string]Schedule
  1446  
  1447  	url, err := b.getAPIPath("/schedules/")
  1448  	if err != nil {
  1449  		return nil, err
  1450  	}
  1451  
  1452  	res, err := get(ctx, url)
  1453  	if err != nil {
  1454  		return nil, err
  1455  	}
  1456  
  1457  	err = unmarshal(res, &r)
  1458  	if err != nil {
  1459  		return nil, err
  1460  	}
  1461  
  1462  	schedules := make([]*Schedule, 0, len(r))
  1463  
  1464  	for i, s := range r {
  1465  		s.ID, err = strconv.Atoi(i)
  1466  		if err != nil {
  1467  			return nil, err
  1468  		}
  1469  		sCopy := s
  1470  		schedules = append(schedules, &sCopy)
  1471  	}
  1472  
  1473  	return schedules, nil
  1474  
  1475  }
  1476  
  1477  // GetSchedule returns one schedule by id defined in i
  1478  func (b *Bridge) GetSchedule(i int) (*Schedule, error) {
  1479  	return b.GetScheduleContext(context.Background(), i)
  1480  }
  1481  
  1482  // GetScheduleContext returns one schedule by id defined in i
  1483  func (b *Bridge) GetScheduleContext(ctx context.Context, i int) (*Schedule, error) {
  1484  
  1485  	g := &Schedule{
  1486  		ID: i,
  1487  	}
  1488  
  1489  	url, err := b.getAPIPath("/schedules/", strconv.Itoa(i))
  1490  	if err != nil {
  1491  		return nil, err
  1492  	}
  1493  
  1494  	res, err := get(ctx, url)
  1495  	if err != nil {
  1496  		return nil, err
  1497  	}
  1498  
  1499  	err = unmarshal(res, &g)
  1500  	if err != nil {
  1501  		return nil, err
  1502  	}
  1503  
  1504  	return g, nil
  1505  
  1506  }
  1507  
  1508  // CreateSchedule creates one schedule and sets its attributes defined in s
  1509  func (b *Bridge) CreateSchedule(s *Schedule) (*Response, error) {
  1510  	return b.CreateScheduleContext(context.Background(), s)
  1511  }
  1512  
  1513  // CreateScheduleContext creates one schedule and sets its attributes defined in s
  1514  func (b *Bridge) CreateScheduleContext(ctx context.Context, s *Schedule) (*Response, error) {
  1515  
  1516  	var a []*APIResponse
  1517  
  1518  	data, err := json.Marshal(&s)
  1519  	if err != nil {
  1520  		return nil, err
  1521  	}
  1522  
  1523  	url, err := b.getAPIPath("/schedules/")
  1524  	if err != nil {
  1525  		return nil, err
  1526  	}
  1527  
  1528  	res, err := post(ctx, url, data)
  1529  	if err != nil {
  1530  		return nil, err
  1531  	}
  1532  
  1533  	err = unmarshal(res, &a)
  1534  	if err != nil {
  1535  		return nil, err
  1536  	}
  1537  
  1538  	resp, err := handleResponse(a)
  1539  	if err != nil {
  1540  		return nil, err
  1541  	}
  1542  
  1543  	return resp, nil
  1544  
  1545  }
  1546  
  1547  // UpdateSchedule updates one schedule by its id of i and attributes by schedule
  1548  func (b *Bridge) UpdateSchedule(i int, schedule *Schedule) (*Response, error) {
  1549  	return b.UpdateScheduleContext(context.Background(), i, schedule)
  1550  }
  1551  
  1552  // UpdateScheduleContext updates one schedule by its id of i and attributes by schedule
  1553  func (b *Bridge) UpdateScheduleContext(ctx context.Context, i int, schedule *Schedule) (*Response, error) {
  1554  
  1555  	var a []*APIResponse
  1556  
  1557  	data, err := json.Marshal(&schedule)
  1558  	if err != nil {
  1559  		return nil, err
  1560  	}
  1561  
  1562  	url, err := b.getAPIPath("/schedules/", strconv.Itoa(i))
  1563  	if err != nil {
  1564  		return nil, err
  1565  	}
  1566  
  1567  	res, err := put(ctx, url, data)
  1568  	if err != nil {
  1569  		return nil, err
  1570  	}
  1571  
  1572  	err = unmarshal(res, &a)
  1573  	if err != nil {
  1574  		return nil, err
  1575  	}
  1576  
  1577  	resp, err := handleResponse(a)
  1578  	if err != nil {
  1579  		return nil, err
  1580  	}
  1581  
  1582  	return resp, nil
  1583  }
  1584  
  1585  // DeleteSchedule deletes one schedule from the bridge by its id of i
  1586  func (b *Bridge) DeleteSchedule(i int) error {
  1587  	return b.DeleteScheduleContext(context.Background(), i)
  1588  }
  1589  
  1590  // DeleteScheduleContext deletes one schedule from the bridge by its id of i
  1591  func (b *Bridge) DeleteScheduleContext(ctx context.Context, i int) error {
  1592  
  1593  	var a []*APIResponse
  1594  
  1595  	id := strconv.Itoa(i)
  1596  	url, err := b.getAPIPath("/schedules/", id)
  1597  	if err != nil {
  1598  		return err
  1599  	}
  1600  
  1601  	res, err := delete(ctx, url)
  1602  	if err != nil {
  1603  		return err
  1604  	}
  1605  
  1606  	_ = unmarshal(res, &a)
  1607  
  1608  	_, err = handleResponse(a)
  1609  	if err != nil {
  1610  		return err
  1611  	}
  1612  
  1613  	return nil
  1614  }
  1615  
  1616  /*
  1617  
  1618  	SENSOR API
  1619  
  1620  */
  1621  
  1622  // GetSensors returns all sensors known to the bridge
  1623  func (b *Bridge) GetSensors() ([]Sensor, error) {
  1624  	return b.GetSensorsContext(context.Background())
  1625  }
  1626  
  1627  // GetSensorsContext returns all sensors known to the bridge
  1628  func (b *Bridge) GetSensorsContext(ctx context.Context) ([]Sensor, error) {
  1629  
  1630  	s := map[string]Sensor{}
  1631  
  1632  	url, err := b.getAPIPath("/sensors/")
  1633  	if err != nil {
  1634  		return nil, err
  1635  	}
  1636  
  1637  	res, err := get(ctx, url)
  1638  	if err != nil {
  1639  		return nil, err
  1640  	}
  1641  
  1642  	err = unmarshal(res, &s)
  1643  	if err != nil {
  1644  		return nil, err
  1645  	}
  1646  
  1647  	sensors := make([]Sensor, 0, len(s))
  1648  
  1649  	for i, k := range s {
  1650  		k.ID, err = strconv.Atoi(i)
  1651  		if err != nil {
  1652  			return nil, err
  1653  		}
  1654  		sensors = append(sensors, k)
  1655  	}
  1656  	return sensors, err
  1657  }
  1658  
  1659  // GetSensor returns one sensor by its id of i
  1660  func (b *Bridge) GetSensor(i int) (*Sensor, error) {
  1661  	return b.GetSensorContext(context.Background(), i)
  1662  }
  1663  
  1664  // GetSensorContext returns one sensor by its id of i
  1665  func (b *Bridge) GetSensorContext(ctx context.Context, i int) (*Sensor, error) {
  1666  
  1667  	r := &Sensor{
  1668  		ID: i,
  1669  	}
  1670  
  1671  	id := strconv.Itoa(i)
  1672  	url, err := b.getAPIPath("/sensors/", id)
  1673  	if err != nil {
  1674  		return nil, err
  1675  	}
  1676  
  1677  	res, err := get(ctx, url)
  1678  	if err != nil {
  1679  		return r, err
  1680  	}
  1681  
  1682  	err = unmarshal(res, &r)
  1683  	if err != nil {
  1684  		return r, err
  1685  	}
  1686  
  1687  	return r, err
  1688  
  1689  }
  1690  
  1691  // CreateSensor creates one new sensor
  1692  func (b *Bridge) CreateSensor(s *Sensor) (*Response, error) {
  1693  	return b.CreateSensorContext(context.Background(), s)
  1694  }
  1695  
  1696  // CreateSensorContext creates one new sensor
  1697  func (b *Bridge) CreateSensorContext(ctx context.Context, s *Sensor) (*Response, error) {
  1698  
  1699  	var a []*APIResponse
  1700  
  1701  	data, err := json.Marshal(&s)
  1702  	if err != nil {
  1703  		return nil, err
  1704  	}
  1705  
  1706  	url, err := b.getAPIPath("/sensors/")
  1707  	if err != nil {
  1708  		return nil, err
  1709  	}
  1710  
  1711  	res, err := post(ctx, url, data)
  1712  	if err != nil {
  1713  		return nil, err
  1714  	}
  1715  
  1716  	err = unmarshal(res, &a)
  1717  	if err != nil {
  1718  		return nil, err
  1719  	}
  1720  
  1721  	resp, err := handleResponse(a)
  1722  	if err != nil {
  1723  		return nil, err
  1724  	}
  1725  
  1726  	return resp, nil
  1727  
  1728  }
  1729  
  1730  // FindSensors starts a search for new sensors.
  1731  // Use GetNewSensors() to verify if new sensors have been discovered in the bridge.
  1732  func (b *Bridge) FindSensors() (*Response, error) {
  1733  	return b.FindSensorsContext(context.Background())
  1734  }
  1735  
  1736  // FindSensorsContext starts a search for new sensors.
  1737  // Use GetNewSensorsContext() to verify if new sensors have been discovered in the bridge.
  1738  func (b *Bridge) FindSensorsContext(ctx context.Context) (*Response, error) {
  1739  
  1740  	var a []*APIResponse
  1741  
  1742  	url, err := b.getAPIPath("/sensors/")
  1743  	if err != nil {
  1744  		return nil, err
  1745  	}
  1746  
  1747  	res, err := post(ctx, url, nil)
  1748  	if err != nil {
  1749  		return nil, err
  1750  	}
  1751  
  1752  	err = unmarshal(res, &a)
  1753  	if err != nil {
  1754  		return nil, err
  1755  	}
  1756  
  1757  	resp, err := handleResponse(a)
  1758  	if err != nil {
  1759  		return nil, err
  1760  	}
  1761  
  1762  	return resp, nil
  1763  
  1764  }
  1765  
  1766  // GetNewSensors returns a list of sensors that were discovered last time GetNewSensors() was executed.
  1767  func (b *Bridge) GetNewSensors() (*NewSensor, error) {
  1768  	return b.GetNewSensorsContext(context.Background())
  1769  }
  1770  
  1771  // GetNewSensorsContext returns a list of sensors that were discovered last time GetNewSensors() was executed.
  1772  func (b *Bridge) GetNewSensorsContext(ctx context.Context) (*NewSensor, error) {
  1773  
  1774  	var n map[string]Sensor
  1775  	var result *NewSensor
  1776  
  1777  	url, err := b.getAPIPath("/sensors/new")
  1778  	if err != nil {
  1779  		return nil, err
  1780  	}
  1781  
  1782  	res, err := get(ctx, url)
  1783  	if err != nil {
  1784  		return nil, err
  1785  	}
  1786  
  1787  	_ = unmarshal(res, &n)
  1788  
  1789  	sensors := make([]*Sensor, 0, len(n))
  1790  
  1791  	for i, l := range n {
  1792  		if i != "lastscan" {
  1793  			l.ID, err = strconv.Atoi(i)
  1794  			if err != nil {
  1795  				return nil, err
  1796  			}
  1797  			lCopy := l
  1798  			sensors = append(sensors, &lCopy)
  1799  		}
  1800  	}
  1801  
  1802  	err = unmarshal(res, &result)
  1803  	if err != nil {
  1804  		return nil, err
  1805  	}
  1806  
  1807  	resu := &NewSensor{sensors, result.LastScan}
  1808  
  1809  	return resu, nil
  1810  
  1811  }
  1812  
  1813  // UpdateSensor updates one sensor by its id and attributes by sensor
  1814  func (b *Bridge) UpdateSensor(i int, sensor *Sensor) (*Response, error) {
  1815  	return b.UpdateSensorContext(context.Background(), i, sensor)
  1816  }
  1817  
  1818  // UpdateSensorContext updates one sensor by its id and attributes by sensor
  1819  func (b *Bridge) UpdateSensorContext(ctx context.Context, i int, sensor *Sensor) (*Response, error) {
  1820  
  1821  	var a []*APIResponse
  1822  
  1823  	data, err := json.Marshal(&sensor)
  1824  	if err != nil {
  1825  		return nil, err
  1826  	}
  1827  
  1828  	url, err := b.getAPIPath("/sensors/", strconv.Itoa(i))
  1829  	if err != nil {
  1830  		return nil, err
  1831  	}
  1832  
  1833  	res, err := put(ctx, url, data)
  1834  	if err != nil {
  1835  		return nil, err
  1836  	}
  1837  
  1838  	err = unmarshal(res, &a)
  1839  	if err != nil {
  1840  		return nil, err
  1841  	}
  1842  
  1843  	resp, err := handleResponse(a)
  1844  	if err != nil {
  1845  		return nil, err
  1846  	}
  1847  
  1848  	return resp, nil
  1849  }
  1850  
  1851  // DeleteSensor deletes one sensor from the bridge
  1852  func (b *Bridge) DeleteSensor(i int) error {
  1853  	return b.DeleteSensorContext(context.Background(), i)
  1854  }
  1855  
  1856  // DeleteSensorContext deletes one sensor from the bridge
  1857  func (b *Bridge) DeleteSensorContext(ctx context.Context, i int) error {
  1858  
  1859  	var a []*APIResponse
  1860  
  1861  	id := strconv.Itoa(i)
  1862  	url, err := b.getAPIPath("/sensors/", id)
  1863  	if err != nil {
  1864  		return err
  1865  	}
  1866  
  1867  	res, err := delete(ctx, url)
  1868  	if err != nil {
  1869  		return err
  1870  	}
  1871  
  1872  	_ = unmarshal(res, &a)
  1873  
  1874  	_, err = handleResponse(a)
  1875  	if err != nil {
  1876  		return err
  1877  	}
  1878  
  1879  	return nil
  1880  }
  1881  
  1882  // UpdateSensorConfig updates the configuration of one sensor. The allowed configuration parameters depend on the sensor type
  1883  func (b *Bridge) UpdateSensorConfig(i int, c interface{}) (*Response, error) {
  1884  	return b.UpdateSensorConfigContext(context.Background(), i, c)
  1885  }
  1886  
  1887  // UpdateSensorConfigContext updates the configuration of one sensor. The allowed configuration parameters depend on the sensor type
  1888  func (b *Bridge) UpdateSensorConfigContext(ctx context.Context, i int, c interface{}) (*Response, error) {
  1889  	var a []*APIResponse
  1890  
  1891  	data, err := json.Marshal(&c)
  1892  	if err != nil {
  1893  		return nil, err
  1894  	}
  1895  
  1896  	url, err := b.getAPIPath("/sensors/", strconv.Itoa(i), "/config")
  1897  	if err != nil {
  1898  		return nil, err
  1899  	}
  1900  
  1901  	res, err := put(ctx, url, data)
  1902  	if err != nil {
  1903  		return nil, err
  1904  	}
  1905  
  1906  	err = unmarshal(res, &a)
  1907  	if err != nil {
  1908  		return nil, err
  1909  	}
  1910  
  1911  	resp, err := handleResponse(a)
  1912  	if err != nil {
  1913  		return nil, err
  1914  	}
  1915  
  1916  	return resp, nil
  1917  }
  1918  
  1919  /*
  1920  
  1921  	CAPABILITIES API
  1922  
  1923  */
  1924  
  1925  // GetCapabilities returns a list of capabilities of resources supported in the bridge.
  1926  func (b *Bridge) GetCapabilities() (*Capabilities, error) {
  1927  	return b.GetCapabilitiesContext(context.Background())
  1928  }
  1929  
  1930  // GetCapabilitiesContext returns a list of capabilities of resources supported in the bridge.
  1931  func (b *Bridge) GetCapabilitiesContext(ctx context.Context) (*Capabilities, error) {
  1932  
  1933  	s := &Capabilities{}
  1934  
  1935  	url, err := b.getAPIPath("/capabilities/")
  1936  	if err != nil {
  1937  		return nil, err
  1938  	}
  1939  
  1940  	res, err := get(ctx, url)
  1941  	if err != nil {
  1942  		return nil, err
  1943  	}
  1944  
  1945  	err = unmarshal(res, &s)
  1946  	if err != nil {
  1947  		return nil, err
  1948  	}
  1949  
  1950  	return s, err
  1951  }