This repository has been archived by the owner on Mar 30, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
musiccast.go
143 lines (123 loc) · 3.41 KB
/
musiccast.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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
package main
import (
"context"
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"time"
"github.com/LouisChrist/streamdeck-musiccast/sdplugin"
)
//Settings data for plugin
type Settings struct {
IP string `json:"IP"`
}
//loadSettings from data or return erro if failed
func loadSettings(payload []byte) (Settings, error) {
var settings Settings
err := json.Unmarshal(payload, &settings)
if err != nil {
return Settings{}, err
}
return settings, nil
}
// contextUpdateWorker keeps the devices power state up to date
func (m *musicCastHandler) contextUpdateWorker(context context.Context, sender sdplugin.Sender, sdContext string) {
ticker := time.NewTicker(10 * time.Second)
defer ticker.Stop()
log.Println("Starting worker")
for true {
select {
case <-ticker.C:
log.Println("Worker update")
m.stateUpdate(sender, sdContext)
case <-context.Done():
log.Println("Stopping worker")
return
}
}
}
// stateUpdate fetches status from musiccast device and updates streamdeck icon
func (m *musicCastHandler) stateUpdate(sender sdplugin.Sender, context string) {
m.contextMapMutex.Lock()
defer m.contextMapMutex.Unlock()
if settings, ok := m.contextMap[context]; ok {
on, err := m.isMusicCastPowerOn(settings.IP)
if err != nil {
log.Printf("Could not check device power status: %v\n", err)
return
}
log.Printf("Is on? %v\n", on)
targetState := 1 //off
if on {
targetState = 0 //on
}
log.Printf("Settings state to %v\n", targetState)
err = sender.SetState(context, targetState)
if err != nil {
log.Printf("Failed to set device state: %v\n", err)
return
}
}
}
func (m *musicCastHandler) setMusicCastPower(ip string, on bool) error {
desiredState := "standby"
if on {
desiredState = "on"
}
resp, err := m.client.Get(fmt.Sprintf("http://%v/YamahaExtendedControl/v1/main/setPower?power=%v", ip, desiredState))
if err != nil {
return err
}
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("Got wrong status code %v", resp.Status)
}
return nil
}
func (m *musicCastHandler) musicCastPowerToggle(ip string) error {
resp, err := m.client.Get(fmt.Sprintf("http://%v/YamahaExtendedControl/v1/main/setPower?power=toggle", ip))
if err != nil {
return err
}
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("Got wrong status code %v", resp.Status)
}
return nil
}
// musicCastStatus struct for getStatus response from MusicCast device.
// Only needed field are present,
type musicCastStatus struct {
Code int `json:"response_code"`
Power string `json:"power"` // standby or on
}
func (m *musicCastHandler) isMusicCastPowerOn(ip string) (bool, error) {
resp, err := m.client.Get(fmt.Sprintf("http://%v/YamahaExtendedControl/v1/main/getStatus", ip))
if err != nil {
return false, err
}
if resp.StatusCode != http.StatusOK {
return false, fmt.Errorf("Got wrong status code %v", resp.Status)
}
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
return false, err
}
resp.Body.Close()
var musicCastStatus musicCastStatus
err = json.Unmarshal(data, &musicCastStatus)
if err != nil {
return false, err
}
if musicCastStatus.Code != 0 {
return false, fmt.Errorf("Error code: %v", musicCastStatus.Code)
}
if musicCastStatus.Power == "standby" {
return false, nil
}
return true, nil
}
// propertyInspectorMessageType is used to differentiate between get and startup messages
type propertyInspectorMessageType struct {
Type string `json:"type"`
}