aboutsummaryrefslogtreecommitdiff
path: root/example_hk.go
diff options
context:
space:
mode:
Diffstat (limited to 'example_hk.go')
-rw-r--r--example_hk.go125
1 files changed, 125 insertions, 0 deletions
diff --git a/example_hk.go b/example_hk.go
new file mode 100644
index 0000000..ee89281
--- /dev/null
+++ b/example_hk.go
@@ -0,0 +1,125 @@
1package main
2
3import (
4 "encoding/json"
5 "fmt"
6 "github.com/brutella/hc"
7 "github.com/brutella/hc/accessory"
8 "github.com/mcrute/go-inform/inform"
9 "io/ioutil"
10 "log"
11 "os"
12)
13
14// Load devices into state
15// Gather current initial state from devices
16// Track state transitions
17// Inputs:
18// - Homekit
19// - Devices
20
21type Port struct {
22 Label string `json:"label"`
23 Port int `json:"port"`
24}
25
26type Device struct {
27 Key string `json:"key"`
28 Name string `json:"name"`
29 Model string `json:"model"`
30 Serial string `json:"serial"`
31 Ports []*Port `json:"ports"`
32}
33
34type DeviceMap map[string]*Device
35
36func LoadKeys(file string) (DeviceMap, error) {
37 var keys DeviceMap
38
39 kp, err := os.Open(file)
40 if err != nil {
41 return nil, err
42 }
43 defer kp.Close()
44
45 kd, err := ioutil.ReadAll(kp)
46 if err != nil {
47 return nil, err
48 }
49
50 err = json.Unmarshal(kd, &keys)
51 if err != nil {
52 return nil, err
53 }
54
55 return keys, nil
56}
57
58func main() {
59 devs, err := LoadKeys("data/device_keys.json")
60 if err != nil {
61 log.Println("Error loading key file")
62 log.Println(err.Error())
63 return
64 }
65
66 keys := make(map[string]string, len(devs))
67 for i, d := range devs {
68 keys[i] = d.Key
69 }
70
71 h := inform.NewInformHandler(&inform.Codec{keys})
72 s, _ := inform.NewServer(h)
73 as := make([]*accessory.Accessory, 0, len(devs)*3)
74
75 for i, d := range devs {
76 for _, p := range d.Ports {
77 a := accessory.NewSwitch(accessory.Info{
78 Name: p.Label,
79 SerialNumber: fmt.Sprintf("%s-%d", d.Serial, p.Port),
80 Manufacturer: "Ubiquiti",
81 Model: d.Model,
82 })
83
84 // Capture these for the closure, otherwise they're bound to the
85 // single loop variable and will only see the final value of that
86 // variable
87 dev, port := i, p.Port
88
89 a.Switch.On.OnValueRemoteUpdate(func(on bool) {
90 h.SetState(dev, port, on)
91 })
92
93 h.AddPort(dev, port)
94 as = append(as, a.Accessory)
95 }
96 }
97
98 // The root accessory is what gets used to name the bridge so let's make it
99 // an actual bridge
100 br := accessory.New(accessory.Info{
101 Name: "UnifiBridge",
102 Manufacturer: "Mike Crute",
103 Model: "0.1",
104 }, accessory.TypeBridge)
105
106 config := hc.Config{
107 Pin: "12344321",
108 Port: "12345",
109 StoragePath: "./db",
110 }
111
112 t, err := hc.NewIPTransport(config, br, as...)
113 if err != nil {
114 log.Fatal(err)
115 return
116 }
117
118 hc.OnTermination(func() {
119 t.Stop()
120 os.Exit(0) // Otherwise homekit doesn't actually stop
121 })
122
123 go t.Start()
124 s.ListenAndServe()
125}