-
Notifications
You must be signed in to change notification settings - Fork 1
/
input.go
194 lines (156 loc) · 6.01 KB
/
input.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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
package kramer
import (
"context"
"fmt"
"strconv"
"strings"
"github.com/byuoitav/common/status"
"github.com/fatih/color"
)
// GetInput returns the current input
func (vs *Kramer4x4) GetAudioVideoInputs(ctx context.Context) (map[string]string, error) {
toReturn := make(map[string]string)
for x := 0; x < 4; x++ {
vs.Log.Debugf("Getting input for output port %d", x)
vs.Log.Debugf("Changing to 1-based indexing... (+1 to each port number)")
cmd := []byte(fmt.Sprintf("#VID? %d\r", x+1))
vs.Log.Debugf("Command: %s", cmd)
resp, err := vs.SendCommand(ctx, cmd)
if err != nil {
vs.Log.Errorf("error sending command: %s", err.Error())
return toReturn, fmt.Errorf("error sending command: %w", err)
}
resps := string(resp)
if !strings.Contains(resps, "VID") {
return toReturn, fmt.Errorf("Incorrect response for command (%s). (Response: %s)", cmd, resps)
}
parts := strings.Split(resps, "VID")
resps = strings.TrimSpace(parts[1])
parts = strings.Split(resps, ">")
var i status.Input
i.Input = parts[0]
vs.Log.Debugf("Changing to 0-based indexing... (-1 to each port number)")
i.Input, err = ToIndexZero(i.Input)
if err != nil {
return toReturn, fmt.Errorf("unable to switch to index zero: %w", err)
}
i.Input = fmt.Sprintf("%v:%v", i.Input, x)
color.Set(color.FgGreen, color.Bold)
vs.Log.Debugf("Input for output port %s is %v", i, i.Input)
toReturn[strconv.Itoa(x)] = i.Input
}
return toReturn, nil
}
// func (vs *Kramer4x4) GetAudioVideoInputs(ctx context.Context) (map[string]string, error) {
// inputs := make(map[string]string)
// cmd := []byte(fmt.Sprintf("#VID? *\n"))
// resp, err := vs.SendCommand(ctx, cmd)
// if err != nil {
// return inputs, fmt.Errorf("error sending command: %w", err)
// }
// split := strings.Split(string(resp), "VID")
// if len(split) != 2 {
// // TODO weird response
// return nil, fmt.Errorf("WEIRD response: %v", split)
// }
// for _, str := range strings.Split(split[1], ",") {
// split := strings.Split(strings.TrimSpace(str), ">")
// if len(split) != 2 {
// // TODO weird response
// return nil, fmt.Errorf("WERID Response: %v", split)
// }
// inputs[split[0]] = split[1]
// }
// return inputs, nil
// }
// SwitchInput changes the input on the given output to input
func (vs *Kramer4x4) SetAudioVideoInput(ctx context.Context, output, input string) error {
i, err := ToIndexOne(input)
if err != nil || LessThanZero(input) {
return fmt.Errorf("error! Input parameter %s is not valid", input)
}
o, err := ToIndexOne(output)
if err != nil || LessThanZero(output) {
return fmt.Errorf("error! Output parameter must be zero or greater")
}
vs.Log.Debugf("Routing %v to %v on %v", input, output, vs.Address)
vs.Log.Debugf("Changing to 1-based indexing... (+1 to each port number)")
cmd := []byte(fmt.Sprintf("#VID %s>%s\r\n", i, o))
resp, err := vs.SendCommand(ctx, cmd)
if err != nil {
vs.Log.Errorf("unable to send command: %s", err.Error())
return fmt.Errorf("unable to send command: %w", err)
}
resps := string(resp)
if !strings.Contains(resps, "VID") {
return fmt.Errorf("Incorrect response for command (%s). (Response: %s)", cmd, resp)
}
return nil
}
// This function converts a number (in a string) to index-base 0.
func ToIndexZero(numString string) (string, error) {
num, err := strconv.Atoi(numString)
if err != nil {
return "", err
}
num--
return strconv.Itoa(num), nil
}
// GetInput returns the current input
// The API is zero indexed, so outputs 0-3 correspond with outputs 1-4 on device
// inputs 0-10 correspond with outputs 1-11 see https://cdn.kramerav.com/web/downloads/manuals/vp-558_rev_4.pdf (page 66)
func (vsdsp *KramerVP558) GetAudioVideoInputs(ctx context.Context) (map[string]string, error) {
toReturn := make(map[string]string)
for x := 0; x < 4; x++ {
vsdsp.Log.Debugf("Getting input for output port %s", x)
cmd := []byte(fmt.Sprintf("#ROUTE? 1,%d\r\n", x))
resp, err := vsdsp.SendCommand(ctx, cmd, false)
if err != nil {
vsdsp.Log.Errorf("error sending command: %s", err.Error())
return toReturn, fmt.Errorf("error sending command: %w", err)
}
resps := string(resp)
if strings.Contains(resps, "ERR") {
return toReturn, fmt.Errorf("Incorrect response for command (%s). (Response: %s)", cmd, resps)
}
resps = strings.TrimSpace(resps)
parts := strings.Split(resps, ",")
if len(parts) != 3 {
return toReturn, fmt.Errorf("Incorrect response for command (%s). (Response: %s)", cmd, resps)
}
var i status.Input
i.Input = parts[2]
// vsdsp.Log.Infof("successfully got input", zap.String("output", output), zap.String("input", i.Input))
toReturn[strconv.Itoa(x)] = i.Input
}
return toReturn, nil
}
// SwitchInput changes the input on the given output to input
// outputs 1-4 on device inputs 1-11 see https://cdn.kramerav.com/web/downloads/manuals/vp-558_rev_4.pdf (page 66)
func (vsdsp *KramerVP558) SetAudioVideoInput(ctx context.Context, output, input string) error {
vsdsp.Log.Debugf("Routing %v to %v on %v", input, output, vsdsp.Address)
// vsdsp.Log.Infof("sending setInput command", zap.String("output", output), zap.String("input", input))
cmd := []byte(fmt.Sprintf("#ROUTE 1,%s,%s\r\n", output, input))
//cheack to see if the current input is going to be changing
currentInputs, err := vsdsp.GetAudioVideoInputs(ctx)
if err != nil {
vsdsp.Log.Errorf("error sending command: %s", err.Error())
return fmt.Errorf("error sending command: %w", err)
}
//if there is a change, two responses will be sent and both need to be read
readAgain := false
if currentInputs[output] != input {
readAgain = true
}
resp, err := vsdsp.SendCommand(ctx, cmd, readAgain)
if err != nil {
vsdsp.Log.Errorf("unable to send command: %s", err.Error())
return fmt.Errorf("unable to send command: %w", err)
}
resps := string(resp)
if strings.Contains(resps, "ERR") {
return fmt.Errorf("Incorrect response for command (%s). (Response: %s)", cmd, resp)
}
// vsdsp.Log.Infof("successfully sent setInput command", zap.String("output", output), zap.String("input", input))
return nil
}