Skip to content

Commit

Permalink
feat: Add interface methods to Home object
Browse files Browse the repository at this point in the history
  • Loading branch information
gonzolino committed Mar 18, 2022
1 parent eab200d commit cdd2c69
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 52 deletions.
36 changes: 10 additions & 26 deletions examples/mischomeinfo/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@ package main
import (
"context"
"fmt"
"net/http"
"os"
"time"

"github.com/gonzolino/gotado"
)
Expand Down Expand Up @@ -35,37 +33,23 @@ func main() {
homeName := os.Args[1]

ctx := context.Background()
tado := gotado.New(clientID, clientSecret)

// Create authenticated tado° client
httpClient := &http.Client{Timeout: 5 * time.Second}
client := gotado.NewClient(clientID, clientSecret).WithHTTPClient(httpClient)
client, err := client.WithCredentials(ctx, username, password)
if err != nil {
fmt.Fprintf(os.Stderr, "Authentication failed: %v\n", err)
os.Exit(1)
}

user, err := gotado.GetMe(client)
user, err := tado.Me(ctx, username, password)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to get user info: %v\n", err)
os.Exit(1)
}

// Find the home to control
var home *gotado.UserHome
for _, h := range user.Homes {
if h.Name == homeName {
home = &h
break
}
}
if home == nil {
fmt.Fprintf(os.Stderr, "Home '%s' not found\n", homeName)
home, err := user.GetHome(ctx, homeName)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to find home '%s': %v\n", homeName, err)
os.Exit(1)
}

// Get weather
weather, err := gotado.GetWeather(client, home)
weather, err := home.GetWeather(ctx)
fmt.Println("Weather:")
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to get weather: %v\n", err)
Expand All @@ -76,7 +60,7 @@ func main() {
fmt.Printf("Weather State: %s\n", weather.WeatherState.Value)

// Get Devices
devices, err := gotado.GetDevices(client, home)
devices, err := home.GetDevices(ctx)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to get devices: %v\n", err)
os.Exit(1)
Expand All @@ -87,7 +71,7 @@ func main() {
}

// Get Installations
installations, err := gotado.GetInstallations(client, home)
installations, err := home.GetInstallations(ctx)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to get installations: %v\n", err)
os.Exit(1)
Expand All @@ -98,7 +82,7 @@ func main() {
}

// Get mobile Devices
mobileDevices, err := gotado.GetMobileDevices(client, home)
mobileDevices, err := home.GetMobileDevices(ctx)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to get mobile devices: %v\n", err)
os.Exit(1)
Expand All @@ -113,7 +97,7 @@ func main() {
}

// Get Users
users, err := gotado.GetUsers(client, home)
users, err := home.GetUsers(ctx)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to get users: %v\n", err)
os.Exit(1)
Expand Down
37 changes: 11 additions & 26 deletions examples/presence/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package main
import (
"context"
"fmt"
"net/http"
"os"
"time"

Expand Down Expand Up @@ -35,37 +34,23 @@ func main() {
homeName := os.Args[1]

ctx := context.Background()
tado := gotado.New(clientID, clientSecret)

// Create authenticated tado° client
httpClient := &http.Client{Timeout: 5 * time.Second}
client := gotado.NewClient(clientID, clientSecret).WithHTTPClient(httpClient)
client, err := client.WithCredentials(ctx, username, password)
if err != nil {
fmt.Fprintf(os.Stderr, "Authentication failed: %v\n", err)
os.Exit(1)
}

user, err := gotado.GetMe(client)
user, err := tado.Me(ctx, username, password)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to get user info: %v\n", err)
os.Exit(1)
}

// Find the home to control
var home *gotado.UserHome
for _, h := range user.Homes {
if h.Name == homeName {
home = &h
break
}
}
if home == nil {
fmt.Fprintf(os.Stderr, "Home '%s' not found\n", homeName)
home, err := user.GetHome(ctx, homeName)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to find home '%s': %v\n", homeName, err)
os.Exit(1)
}

// Get current presence from home state
state, err := gotado.GetHomeState(client, home)
state, err := home.GetState(ctx)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to get home state: %v\n", err)
os.Exit(1)
Expand All @@ -78,7 +63,7 @@ func main() {
}

// Lock presence to 'away'
if err := gotado.SetPresenceAway(client, home); err != nil {
if err := home.SetPresenceAway(ctx); err != nil {
fmt.Fprintf(os.Stderr, "Failed to set presence 'away': %v", err)
os.Exit(1)
}
Expand All @@ -87,7 +72,7 @@ func main() {
time.Sleep(10 * time.Second)

// Lock presence to 'at home'
if err := gotado.SetPresenceHome(client, home); err != nil {
if err := home.SetPresenceHome(ctx); err != nil {
fmt.Fprintf(os.Stderr, "Failed to set presence 'home': %v", err)
os.Exit(1)
}
Expand All @@ -96,7 +81,7 @@ func main() {
time.Sleep(10 * time.Second)

// Set auto presence
if err := gotado.SetPresenceAuto(client, home); err != nil {
if err := home.SetPresenceAuto(ctx); err != nil {
fmt.Fprintf(os.Stderr, "Failed to set presence 'auto': %v", err)
os.Exit(1)
}
Expand All @@ -108,9 +93,9 @@ func main() {
if state.PresenceLocked {
switch state.Presence {
case "HOME":
err = gotado.SetPresenceHome(client, home)
err = home.SetPresenceHome(ctx)
case "AWAY":
err = gotado.SetPresenceAway(client, home)
err = home.SetPresenceAway(ctx)
}

if err != nil {
Expand Down
111 changes: 111 additions & 0 deletions home.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package gotado

import (
"context"
"fmt"
)

// GetHomeState returns the state of the home
func (h *Home) GetState(ctx context.Context) (*HomeState, error) {
homeState := &HomeState{}
if err := h.client.get(ctx, apiURL("homes/%d/state", h.ID), homeState); err != nil {
return nil, err
}
return homeState, nil
}

// GetZones returns information about the zones in the home
func (h *Home) GetZones(ctx context.Context) ([]*Zone, error) {
zones := make([]*Zone, 0)
if err := h.client.get(ctx, apiURL("homes/%d/zones", h.ID), &zones); err != nil {
return nil, err
}
for _, zone := range zones {
zone.client = h.client
}
return zones, nil
}

func (h *Home) GetZone(ctx context.Context, name string) (*Zone, error) {
zones, err := h.GetZones(ctx)
if err != nil {
return nil, fmt.Errorf("unable to list zones: %w", err)
}
for _, zone := range zones {
if zone.Name == name {
return zone, nil
}
}
return nil, fmt.Errorf("unknown zone name '%s'", name)
}

// GetWeather returns weather information at the homes location
func (h *Home) GetWeather(ctx context.Context) (*Weather, error) {
weather := &Weather{}
if err := h.client.get(ctx, apiURL("homes/%d/weather", h.ID), weather); err != nil {
return nil, err
}
return weather, nil
}

// GetDevices lists all devices in the home
func (h *Home) GetDevices(ctx context.Context) ([]*Device, error) {
devices := make([]*Device, 0)
if err := h.client.get(ctx, apiURL("homes/%d/devices", h.ID), &devices); err != nil {
return nil, err
}
for _, device := range devices {
device.client = h.client
}
return devices, nil
}

// GetInstallations lists all installations in the home
func (h *Home) GetInstallations(ctx context.Context) ([]*Installation, error) {
installations := make([]*Installation, 0)
if err := h.client.get(ctx, apiURL("homes/%d/installations", h.ID), &installations); err != nil {
return nil, err
}
return installations, nil
}

// GetMobileDevices lists all mobile devices linked to the home
func (h *Home) GetMobileDevices(ctx context.Context) ([]*MobileDevice, error) {
mobileDevices := make([]*MobileDevice, 0)
if err := h.client.get(ctx, apiURL("homes/%d/mobileDevices", h.ID), &mobileDevices); err != nil {
return nil, err
}
for _, mobileDevice := range mobileDevices {
mobileDevice.client = h.client
}
return mobileDevices, nil
}

// GetUsers lists all users and their mobile devices linked to the home
func (h *Home) GetUsers(ctx context.Context) ([]*User, error) {
users := make([]*User, 0)
if err := h.client.get(ctx, apiURL("homes/%d/users", h.ID), &users); err != nil {
return nil, err
}
for _, user := range users {
user.client = h.client
}
return users, nil
}

// SetPresenceHome sets the geofencing presence to 'at home'.
func (h *Home) SetPresenceHome(ctx context.Context) error {
presence := PresenceLock{HomePresence: PresenceHome}
return h.client.put(ctx, apiURL("homes/%d/presenceLock", h.ID), presence)
}

// SetPresenceAway sets the geofencing presence to 'away'.
func (h *Home) SetPresenceAway(ctx context.Context) error {
presence := PresenceLock{HomePresence: PresenceAway}
return h.client.put(ctx, apiURL("homes/%d/presenceLock", h.ID), presence)
}

// SetPresenceAuto enables geofencing auto mode.
func (h *Home) SetPresenceAuto(ctx context.Context) error {
return h.client.delete(ctx, apiURL("homes/%d/presenceLock", h.ID))
}
3 changes: 3 additions & 0 deletions models.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ const (

// Zone represents a tado° zone
type Zone struct {
client *client
ID int32 `json:"id"`
Name string `json:"name"`
Type ZoneType `json:"type"`
Expand Down Expand Up @@ -400,6 +401,7 @@ type Weather struct {

// Device represents a tado° device such as a thermostat or a bridge
type Device struct {
client *client
DeviceType DeviceType `json:"deviceType"`
SerialNo string `json:"serialNo"`
ShortSerialNo string `json:"shortSerialNo"`
Expand Down Expand Up @@ -442,6 +444,7 @@ type Installation struct {

// MobileDevice represents a mobile device with the tado° app installed
type MobileDevice struct {
client *client
Name string `json:"name"`
ID int32 `json:"id"`
Settings MobileDeviceSettings `json:"settings"`
Expand Down

0 comments on commit cdd2c69

Please sign in to comment.