func (s *Shade) Move(bottom, top uint16) error {
	req, err := http.NewRequest("PUT", "http://"+s.Hub.ip+"/api/shades/"+fmt.Sprint(s.ID),
		strings.NewReader(fmt.Sprintf(`{"shade":{"id":%d,"positions":{"posKind2":2,"position2":%d,"posKind1":1,"position1":%d}}}`,
			s.ID, top, bottom)))
	req.Header.Set("Content-Type", "application/json; charset=UTF-8")
	if err != nil {
		return err
	}
	res, err := s.Hub.do(req)
	if err != nil {
		return err
	}
	s.Bottom = bottom
	s.Top = top
	res.Body.Close()
	return nil
}
Move moves the shade.
package powerview
import (
	"encoding/json"
	"errors"
	"fmt"
	"net/http"
	"sort"
	"strings"
	"time"
)
type Hub struct {
	ip string
}
func (h *Hub) get(path string) (*http.Response, error) {
	req, _ := http.NewRequest("GET", "http://"+h.ip+path, nil)
	if strings.HasSuffix(path, "?") {
		req.URL.Opaque = path
	}
	return h.do(req)
}
func (h *Hub) do(req *http.Request) (*http.Response, error) {
	cancel := make(chan struct{})
	req.Cancel = cancel
	timer := time.AfterFunc(1*time.Second, func() { close(cancel) })
	defer timer.Stop()
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		return nil, err
	}
	if res.StatusCode != 200 {
		return nil, fmt.Errorf("powerview hub: %v", res.Status)
	}
	return res, nil
}
func NewHub(ip string) *Hub {
	return &Hub{ip: ip}
}
type Scenes struct {
	h   *Hub
	res scenesJSON
}
type Scene struct {
	Hub  *Hub
	ID   int64
	Name string
	Room *Room
}
func (s *Scene) Do() error {
	if s == nil {
		return errors.New("nil scene")
	}
	res, err := s.Hub.get("/api/scenes?sceneid=" + fmt.Sprint(s.ID))
	if err != nil {
		return err
	}
	res.Body.Close()
	return nil
}
type Room struct {
	h    *Hub
	ID   int64
	Name string  
}
func (s *Scenes) Map() map[string]*Scene {
	m := map[string]*Scene{}
	for _, d := range s.res.Scenes {
		s := &Scene{
			Hub:  s.h,
			Name: string(d.Name),
			ID:   d.ID,
			Room: &Room{
				ID: d.RoomID,
				h:  s.h,
			},
		}
		m[s.Name] = s
	}
	return m
}
func (s *Scenes) ByName() []*Scene {
	m := s.Map()
	names := make([]string, 0, len(m))
	scenes := make([]*Scene, 0, len(m))
	for name := range m {
		names = append(names, name)
	}
	sort.Strings(names)
	for _, name := range names {
		scenes = append(scenes, m[name])
	}
	return scenes
}
func (s *Shades) Map() map[string]*Shade {
	m := map[string]*Shade{}
	for _, d := range s.res.Shades {
		s := &Shade{
			Hub:             s.h,
			Name:            string(d.Name),
			ID:              d.ID,
			BatteryStrength: d.BatteryStrength,
			BatteryStatus:   d.BatteryStatus,
			BatteryIsLow:    d.BatteryIsLow,
			Bottom:          d.Positions["position1"],
			Top:             d.Positions["position2"],
		}
		m[s.Name] = s
	}
	return m
}
func (s *Shades) ByName() []*Shade {
	m := s.Map()
	names := make([]string, 0, len(m))
	shades := make([]*Shade, 0, len(m))
	for name := range m {
		names = append(names, name)
	}
	sort.Strings(names)
	for _, name := range names {
		shades = append(shades, m[name])
	}
	return shades
}
func (h *Hub) Scenes() (*Scenes, error) {
	res, err := h.get("/api/scenes?")  
	if err != nil {
		return nil, err
	}
	defer res.Body.Close()
	sl := &Scenes{h: h}
	if err := json.NewDecoder(res.Body).Decode(&sl.res); err != nil {
		return nil, err
	}
	return sl, nil
}
type Rooms struct {
	h   *Hub
	res roomsJSON
}
func (s *Rooms) Map() map[string]*Room {
	m := map[string]*Room{}
	for _, d := range s.res.Rooms {
		s := &Room{
			h:    s.h,
			Name: string(d.Name),
			ID:   d.ID,
		}
		m[s.Name] = s
	}
	return m
}
func (s *Rooms) ByName() []*Room {
	m := s.Map()
	names := make([]string, 0, len(m))
	rooms := make([]*Room, 0, len(m))
	for name := range m {
		names = append(names, name)
	}
	sort.Strings(names)
	for _, name := range names {
		rooms = append(rooms, m[name])
	}
	return rooms
}
func (h *Hub) Rooms() (*Rooms, error) {
	res, err := h.get("/api/rooms?")  
	if err != nil {
		return nil, err
	}
	defer res.Body.Close()
	rs := &Rooms{h: h}
	if err := json.NewDecoder(res.Body).Decode(&rs.res); err != nil {
		return nil, err
	}
	return rs, nil
}
type Shades struct {
	h   *Hub
	res shadesJSON
}
type Shade struct {
	Hub             *Hub
	ID              int64
	Name            string
	BatteryStrength int64
	BatteryStatus   int64
	BatteryIsLow    bool
	Bottom uint16
	Top uint16
}