-
Notifications
You must be signed in to change notification settings - Fork 1
/
config.go
119 lines (102 loc) · 2.77 KB
/
config.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
package ezhub
import (
"context"
"crypto/rand"
"fmt"
"io"
"math"
"math/big"
"time"
"github.com/function61/gokit/encoding/jsonfile"
. "github.com/function61/hautomo/pkg/builtin"
"github.com/function61/hautomo/pkg/changedetector"
"github.com/function61/hautomo/pkg/ezstack/coordinator"
"github.com/function61/hautomo/pkg/ezstack/zigbee"
)
type Config struct {
Coordinator coordinator.Configuration
HttpAddr string `json:"HttpAddr,omitempty"`
MQTT *MQTTConfig `json:"MQTT,omitempty"`
}
func (c Config) Valid() error {
return FirstError(
c.Coordinator.Valid(),
c.MQTT.Valid())
}
type MQTTConfig struct {
Prefix string // e.g. "ezhub" => device states are published to ezhub/<device>
Addr string // e.g. "127.0.0.1:1883"
}
func (m MQTTConfig) Valid() error {
return FirstError(
ErrorIfUnset(m.Prefix == "", "Prefix"),
ErrorIfUnset(m.Addr == "", "Addr"))
}
func createStateSnapshotTask(nodeDatabase *nodeDb) func(ctx context.Context) error {
return func(ctx context.Context) error {
saveTimer := time.NewTicker(30 * time.Second)
stateChangeDetector := changedetector.New()
saveIfChanged := func() error {
changed, err := stateChangeDetector.WriterChanged(func(sink io.Writer) error {
return jsonfile.Marshal(sink, nodeDatabase)
})
if err != nil {
return err
}
if changed {
return saveNodeDatabase(nodeDatabase)
} else {
return nil
}
}
for {
select {
case <-ctx.Done():
return saveIfChanged()
case <-saveTimer.C:
if err := saveIfChanged(); err != nil {
return err // unable to write to disk is worth a crash
}
}
}
}
}
func GenerateConfiguration(output io.Writer) error {
coordinatorIEEEAddress := make([]byte, 8)
if _, err := rand.Read(coordinatorIEEEAddress); err != nil {
return err
}
networkKey := make([]byte, len(zigbee.NetworkKey{}))
if _, err := rand.Read(networkKey); err != nil {
return err
}
// 0x3fff = thanks for the surprise. not uint16 but surpriseint16. makes sense.
// https://www.eetimes.com/zigbee-applications-part-4-zigbee-addressing/
panId, err := rand.Int(rand.Reader, big.NewInt(0x3fff))
if err != nil {
return err
}
extPanId, err := rand.Int(rand.Reader, big.NewInt(math.MaxInt64))
if err != nil {
return err
}
conf := Config{
Coordinator: coordinator.Configuration{
NetworkConfiguration: coordinator.NetworkConfiguration{
PanId: zigbee.PANID(panId.Int64()),
ExtPanId: zigbee.ExtendedPANID(extPanId.Uint64()),
IEEEAddress: zigbee.IEEEAddress(fmt.Sprintf("0x%x", coordinatorIEEEAddress)),
NetworkKey: networkKey,
Channel: 15,
},
Serial: &coordinator.Serial{
Port: "/dev/ttyACM0",
},
},
MQTT: &MQTTConfig{
Prefix: "ezhub1",
Addr: "127.0.0.1:1883",
},
}
return jsonfile.Marshal(output, conf)
}