-
Notifications
You must be signed in to change notification settings - Fork 1
/
adapter.go
executable file
·106 lines (87 loc) · 2.58 KB
/
adapter.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
// Sync state from Hautomo to Home Assistant, along with support for pushing remote URL
// changes (images / RSS feeds) to Home Assistant
package homeassistantadapter
import (
"context"
"fmt"
"time"
"github.com/function61/gokit/log/logex"
"github.com/function61/hautomo/pkg/hapitypes"
"github.com/function61/hautomo/pkg/homeassistant"
)
var (
topicPrefix = homeassistant.NewTopicPrefix("hautomo")
)
func Start(ctx context.Context, adapter *hapitypes.Adapter) error {
ha, mqttTask := homeassistant.NewMQTTClient(
homeassistant.MQTTConfig{
Address: adapter.Conf.Url,
},
"Hautomo-Home-Assistant",
adapter.Logl)
homeAssistantInboundCommand, err := ha.SubscribeForCommands(topicPrefix)
if err != nil {
return err
}
entityById := map[string]*homeassistant.Entity{}
allEntities := []*homeassistant.Entity{}
for _, dev := range adapter.GetConfigFileDeprecated().Devices {
typ, err := hapitypes.ResolveDeviceType(dev.Type)
if err != nil {
return err
}
if !typ.Capabilities.VirtualSwitch {
continue
}
switchEntity := homeassistant.NewSwitch(dev.AdaptersDeviceId, dev.Name)
entityById[switchEntity.Id] = switchEntity
allEntities = append(allEntities, switchEntity)
}
pollingTasks := []func(context.Context) error{}
for _, urlChangeDetector := range adapter.Conf.UrlChangeDetectors {
sensor, task := makeUrlCheckerSensor(
urlChangeDetector.Id,
urlChangeDetector.Url,
ha,
adapter.Logl)
allEntities = append(allEntities, sensor)
pollingTasks = append(pollingTasks, task)
}
if err := ha.AutodiscoverEntities(allEntities...); err != nil {
return err
}
runPollingTasks := func() {
_ = launchAndWaitMany(ctx, func(err error) {
adapter.Logl.Error.Println(err)
}, pollingTasks...)
}
// initial sync
runPollingTasks()
pollInterval := time.NewTicker(1 * time.Minute)
for {
select {
case <-ctx.Done():
return nil
case cmd := <-homeAssistantInboundCommand:
entity, found := entityById[cmd.EntityId]
if !found {
return fmt.Errorf("entityById: not found: %s", cmd.EntityId)
}
switch cmd.Payload {
case "ON":
adapter.Receive(hapitypes.NewPowerEvent(cmd.EntityId, hapitypes.PowerKindOn, true))
case "OFF":
adapter.Receive(hapitypes.NewPowerEvent(cmd.EntityId, hapitypes.PowerKindOff, true))
default:
adapter.Logl.Error.Printf("unrecognized state: %s", cmd.Payload)
}
// immediately send state back
// TODO: don't do this from here
if err := ha.PublishState(entity, cmd.State); err != nil {
adapter.Logl.Error.Printf("PublishState: %v", err)
}
case <-pollInterval.C:
runPollingTasks()
}
}
}