Skip to content

Commit 099ca09

Browse files
committed
More abstractions
1 parent 138a47d commit 099ca09

File tree

16 files changed

+194
-70
lines changed

16 files changed

+194
-70
lines changed

cmd/autodidact/main.go

+6-25
Original file line numberDiff line numberDiff line change
@@ -5,46 +5,27 @@ import (
55
"os"
66
"strconv"
77

8-
"github.com/brutella/hc"
9-
"github.com/brutella/hc/accessory"
8+
"github.com/mastery-la/autodidact/pkg/protocol/homekit"
109

1110
"github.com/mastery-la/autodidact/pkg/bridge"
1211

1312
"github.com/joho/godotenv"
1413
)
1514

1615
func main() {
17-
info := accessory.Info{
18-
Name: "Thermostat",
19-
SerialNumber: "TCAS3AS14AS3",
20-
Manufacturer: "Honeywell",
21-
Model: "TCC01",
22-
}
23-
acc := accessory.NewThermostat(info, 22.0, 15.0, 32.0, 1.0)
24-
25-
config := hc.Config{Pin: "12344321", Port: "12345", StoragePath: "./.db"}
26-
t, err := hc.NewIPTransport(config, acc.Accessory)
27-
if err != nil {
28-
log.Panic(err)
29-
}
30-
31-
bridge, err := getBridge()
16+
honeywell, err := getHoneywellThermostat()
3217
if err != nil {
3318
log.Panic(err)
3419
}
3520

36-
acc.Thermostat.TargetTemperature.OnValueRemoteUpdate(func(temp float64) {
37-
bridge.Thermostat.Thermostat.TargetTemperature.SetValue(temp)
38-
})
21+
transport := homekit.New("12344321", "12345", "./db")
3922

40-
hc.OnTermination(func() {
41-
<-t.Stop()
42-
})
23+
transport.AddAccessory(homekit.NewThermostat(honeywell.Thermostat))
4324

44-
t.Start()
25+
transport.Start()
4526
}
4627

47-
func getBridge() (*bridge.HoneywellThermostat, error) {
28+
func getHoneywellThermostat() (*bridge.HoneywellThermostat, error) {
4829
err := godotenv.Load()
4930
if err != nil {
5031
log.Fatal("Error loading .env file")

go.mod

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ module github.com/mastery-la/autodidact
33
require (
44
github.com/brutella/hc v1.2.0
55
github.com/go-home-iot/honeywell v0.0.0-20161119014616-f4dde0984b6b
6+
github.com/iancoleman/strcase v0.0.0-20190422225806-e506e3ef7365
67
github.com/joho/godotenv v1.3.0
78
github.com/labstack/echo v3.3.10+incompatible
89
github.com/labstack/gommon v0.3.0 // indirect

go.sum

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ github.com/go-home-iot/honeywell v0.0.0-20161119014616-f4dde0984b6b h1:GHDOb7k5x
1010
github.com/go-home-iot/honeywell v0.0.0-20161119014616-f4dde0984b6b/go.mod h1:wlxsHBYIAM/4V+1dTa5TehzXaght6AjqzG2v2dsWiu4=
1111
github.com/gosexy/to v0.0.0-20141221203644-c20e083e3123 h1:6Q7VB4v0aEgIE6BtsbJhEH0KgFE0f+FHAxXePQp9Klc=
1212
github.com/gosexy/to v0.0.0-20141221203644-c20e083e3123/go.mod h1:oQuuq9ZkoRpy+2mhINlY3ZrwgywR77yPXmFpP6vCr/w=
13+
github.com/iancoleman/strcase v0.0.0-20190422225806-e506e3ef7365 h1:ECW73yc9MY7935nNYXUkK7Dz17YuSUI9yqRqYS8aBww=
14+
github.com/iancoleman/strcase v0.0.0-20190422225806-e506e3ef7365/go.mod h1:SK73tn/9oHe+/Y0h39VT4UCxmurVJkR5NA7kMEAOgSE=
1315
github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
1416
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
1517
github.com/labstack/echo v3.3.10+incompatible h1:pGRcYk231ExFAyoAjAfD85kQzRJCRI8bbnE7CX5OEgg=

pkg/attribute/attribute.go

+8-6
Original file line numberDiff line numberDiff line change
@@ -7,26 +7,28 @@ type ChangeFunc func(a *Attribute, newValue, oldValue interface{})
77
// Attribute represents a value of a Component and methods for changing
88
// the internal value in a safe way, also notifying listerns of changes
99
type Attribute struct {
10-
attributeType string
11-
format string
12-
value interface{}
10+
id string
11+
typ string
12+
format string
13+
value interface{}
1314

1415
onChange *ChangeFunc
1516
}
1617

1718
// New returns an Attribute for a provided type
18-
func New(typ string) *Attribute {
19+
func New(id string, typ string) *Attribute {
1920
a := new(Attribute)
2021

21-
a.attributeType = typ
22+
a.id = id
23+
a.typ = typ
2224
a.value = nil
2325

2426
return a
2527
}
2628

2729
// GetType returns the type of the Attribute
2830
func (a *Attribute) GetType() string {
29-
return a.attributeType
31+
return a.typ
3032
}
3133

3234
// GetFormat returns the format of the Attribute

pkg/attribute/float.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ type Float struct {
99
}
1010

1111
// NewFloat returns a new Float Attribute
12-
func NewFloat(typ string) *Float {
12+
func NewFloat(id string, typ string) *Float {
1313
f := new(Float)
1414

15-
f.Attribute = New(typ)
15+
f.Attribute = New(id, typ)
1616

1717
f.format = FormatFloat
1818
f.value = 0.0

pkg/attribute/temperature.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ type Temperature struct {
1313
}
1414

1515
// NewTemperature returns a new Temperature Attribute
16-
func NewTemperature() *Temperature {
16+
func NewTemperature(id string) *Temperature {
1717
temp := new(Temperature)
1818

19-
temp.Float = NewFloat(TypeTemperature)
19+
temp.Float = NewFloat(id, TypeTemperature)
2020

2121
return temp
2222
}

pkg/bridge/honeywell.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ import (
1313

1414
type HoneywellThermostat struct {
1515
*Bridge
16-
Thermostat *node.Thermostat
17-
TotalComfortControl *controller.TotalComfortControl
16+
*node.Thermostat
17+
controller *controller.TotalComfortControl
1818
}
1919

2020
func NewHoneywellThermostat(deviceID int, login string, password string) (*HoneywellThermostat, error) {
@@ -31,7 +31,7 @@ func NewHoneywellThermostat(deviceID int, login string, password string) (*Honey
3131
return nil, err
3232
}
3333

34-
hw.TotalComfortControl = tcc
34+
hw.controller = tcc
3535
hw.AddController(tcc.Controller)
3636

3737
hw.setupBridge()
@@ -49,6 +49,6 @@ func (b *HoneywellThermostat) setupBridge() {
4949

5050
temp := newValue.(float64)
5151
log.Printf("client wants %g", temp)
52-
b.TotalComfortControl.SetCoolC(temp)
52+
b.controller.SetCoolC(temp)
5353
})
5454
}

pkg/component/component.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,17 @@ import (
88
// Component represents a compontent of a Node which is made
99
// up of Attributes that can be read from and/or written to
1010
type Component struct {
11-
id string
12-
componentType string
13-
attributes []*attribute.Attribute
11+
id string
12+
typ string
13+
attributes []*attribute.Attribute
1414
}
1515

1616
// New returns a new Component given an id and type
1717
func New(id string, typ string) *Component {
1818
c := new(Component)
1919

2020
c.id = id
21-
c.componentType = typ
21+
c.typ = typ
2222

2323
return c
2424
}
@@ -30,7 +30,7 @@ func (c *Component) GetID() string {
3030

3131
// GetType returns the type of the Component
3232
func (c *Component) GetType() string {
33-
return c.componentType
33+
return c.typ
3434
}
3535

3636
// GetAttributes returns an array of all Attributes of the Component

pkg/component/switch.go

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package component
2+
3+
import (
4+
"github.com/mastery-la/autodidact/pkg/attribute"
5+
)
6+
7+
// TypeSwitch is SwitchComponent
8+
const TypeSwitch = "SwitchComponent"
9+
10+
// Switch is a type of Component that has an on/off attribute
11+
type Switch struct {
12+
*Component
13+
On *attribute.Temperature
14+
}
15+
16+
// NewSwitch creates a Switch Component with a provided id
17+
func NewSwitch(id string) *Switch {
18+
s := new(Switch)
19+
20+
s.Component = New(id, TypeSwitch)
21+
22+
s.On = attribute.NewTemperature("On")
23+
s.AddAttribute(s.On.Attribute)
24+
25+
return s
26+
}

pkg/component/thermostat.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@ func NewThermostat(id string) *Thermostat {
2222

2323
ts.Component = New(id, TypeThermostat)
2424

25-
ts.CurrentTemperature = attribute.NewTemperature()
25+
ts.CurrentTemperature = attribute.NewTemperature("CurrentTemperature")
2626
ts.AddAttribute(ts.CurrentTemperature.Attribute)
2727

28-
ts.TargetTemperature = attribute.NewTemperature()
28+
ts.TargetTemperature = attribute.NewTemperature("TargetTemperature")
2929
ts.AddAttribute(ts.TargetTemperature.Attribute)
3030

3131
return ts

pkg/controller/tccapi.go

+7-4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package controller
33
import (
44
"context"
55
"log"
6+
"math"
67

78
"github.com/mastery-la/autodidact/pkg/util"
89

@@ -31,13 +32,15 @@ func NewTotalComfortControl(ctx context.Context, deviceID int, login string, pas
3132
}
3233

3334
func (c *TotalComfortControl) SetCoolF(temp float64) {
34-
log.Printf("setting cool point to %gºF\n", temp)
35-
c.ts.CoolMode(c.ctx, float32(temp), 0)
35+
setPoint := math.Round(temp)
36+
log.Printf("setting cool point to %gºF\n", setPoint)
37+
c.ts.CoolMode(c.ctx, float32(setPoint), 0)
3638
}
3739

3840
func (c *TotalComfortControl) SetHeatF(temp float64) {
39-
log.Printf("setting heat point to %gºF\n", temp)
40-
c.ts.HeatMode(c.ctx, float32(temp), 0)
41+
setPoint := math.Round(temp)
42+
log.Printf("setting heat point to %gºF\n", setPoint)
43+
c.ts.HeatMode(c.ctx, float32(setPoint), 0)
4144
}
4245

4346
func (c *TotalComfortControl) SetCoolC(temp float64) {

pkg/node/node.go

+23-3
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ package node
33

44
import (
55
"encoding/json"
6+
"strings"
7+
8+
"github.com/iancoleman/strcase"
69

710
"github.com/mastery-la/autodidact/pkg/component"
811
)
@@ -11,28 +14,45 @@ import (
1114
// send messages to and query for metrics
1215
type Node struct {
1316
id string
14-
nodeType string
17+
typ string
1518
components []*component.Component
19+
20+
Name string
21+
Manufacturer string
22+
SerialNumber string
23+
Model string
1624
}
1725

1826
// New returns a new Node given an id and type
1927
func New(id string, typ string) *Node {
2028
node := new(Node)
2129

2230
node.id = id
23-
node.nodeType = typ
31+
node.typ = typ
32+
33+
node.Name = nameFromType(typ)
34+
node.Manufacturer = ""
35+
node.SerialNumber = ""
36+
node.Model = ""
2437

2538
return node
2639
}
2740

41+
func nameFromType(typ string) string {
42+
s := strcase.ToDelimited(typ, '/')
43+
ss := strings.Split(s, "/")
44+
45+
return ss[0]
46+
}
47+
2848
// GetID returns the ID of the Node
2949
func (n *Node) GetID() string {
3050
return n.id
3151
}
3252

3353
// GetType returns the Type of the Node
3454
func (n *Node) GetType() string {
35-
return n.nodeType
55+
return n.typ
3656
}
3757

3858
// GetComponents returns an array of all Components of the Node

pkg/node/thermostat.go

+4-17
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@ import (
99
// TypeThermostat is ThermostatNode
1010
const TypeThermostat = "ThermostatNode"
1111

12-
// Thermostat is a type of Node that represents a thermostat
12+
// Thermostat is a type of Node that represents a thermostat.
13+
// A Thermostat Node is made up of a Thermostat Component
1314
type Thermostat struct {
1415
*Node
15-
Thermostat *component.Thermostat
16+
*component.Thermostat
17+
*component.Switch
1618
}
1719

1820
// NewThermostat creates a Thermostat Node with the provided id
@@ -27,21 +29,6 @@ func NewThermostat(id string) *Thermostat {
2729
return ts
2830
}
2931

30-
// SetTargetTemperature sets the target temperature set point for the thermostat
31-
func (t *Thermostat) SetTargetTemperature(temp float64) {
32-
t.Thermostat.TargetTemperature.SetValue(temp)
33-
}
34-
35-
// GetTargetTemperature gets the target temperature set point for the thermostat
36-
func (t *Thermostat) GetTargetTemperature() float64 {
37-
return t.Thermostat.TargetTemperature.GetValue()
38-
}
39-
40-
// GetCurrentTemperature gets the current temperature as measured by the thermostat
41-
func (t *Thermostat) GetCurrentTemperature() float64 {
42-
return t.Thermostat.CurrentTemperature.GetValue()
43-
}
44-
4532
type thermostatPayload struct {
4633
Node *Node `json:"node"`
4734
Components thermostatComponentsPayload `json:"components"`

0 commit comments

Comments
 (0)