aca-device-modules 1.0.4 → 1.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/aca-device-modules/version.rb +1 -1
- data/modules/aca/lifter_logic_auto.rb +71 -0
- data/modules/aca/lifter_logic_manual.rb +105 -0
- data/modules/aca/pc_control.rb +111 -111
- data/modules/axis/camera/vapix.rb +10 -3
- data/modules/biamp/nexia.rb +149 -128
- data/modules/bss/blu100.rb +8 -8
- data/modules/chiyu/cyt.rb +6 -1
- data/modules/clipsal/c_bus.rb +233 -235
- data/modules/epson/projector/esc_vp21.rb +232 -232
- data/modules/extron/mixer/dmp44.rb +174 -174
- data/modules/extron/mixer/dmp64.rb +192 -181
- data/modules/extron/switcher/dxp.rb +210 -210
- data/modules/global_cache/gc100.rb +6 -2
- data/modules/kramer/switcher/protocol3000.rb +209 -209
- data/modules/kramer/switcher/vs_hdmi.rb +111 -110
- data/modules/nec/display/all.rb +440 -443
- data/modules/nec/projector/np_series.rb +609 -597
- data/modules/panasonic/camera/he50.rb +1 -1
- data/modules/panasonic/projector/tcp.rb +239 -234
- data/modules/philips/dynalite.rb +196 -0
- data/modules/samsung/displays/md_series.rb +34 -16
- data/modules/screen_technics/connect.rb +53 -53
- data/modules/sony/display/id_talk.rb +275 -275
- data/modules/sony/projector/pj_talk.rb +257 -257
- data/modules/vaddio/camera/clear_view_ptz_telnet.rb +7 -3
- metadata +6 -3
data/modules/biamp/nexia.rb
CHANGED
@@ -5,141 +5,162 @@ module Biamp; end
|
|
5
5
|
# TELNET port 23
|
6
6
|
|
7
7
|
class Biamp::Nexia
|
8
|
-
|
8
|
+
include ::Orchestrator::Constants
|
9
9
|
include ::Orchestrator::Transcoder
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
|
11
|
+
def on_load
|
12
|
+
self[:fader_min] = -36 # specifically for tonsley
|
13
|
+
self[:fader_max] = 12
|
14
14
|
|
15
|
-
|
16
|
-
|
15
|
+
# max +12
|
16
|
+
# min -100
|
17
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
|
-
|
18
|
+
config({
|
19
|
+
tokenize: true,
|
20
|
+
delimiter: /\xFF\xFE\x01|\r\n/
|
21
|
+
})
|
22
|
+
end
|
23
|
+
|
24
|
+
def on_unload
|
25
|
+
end
|
26
|
+
|
27
|
+
def on_update
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
def connected
|
32
|
+
send("\xFF\xFE\x01") # Echo off
|
33
|
+
do_send('GETD', 0, 'DEVID')
|
34
|
+
|
35
|
+
@polling_timer = schedule.every('60s') do
|
36
|
+
do_send('GETD', 0, 'DEVID')
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def disconnected
|
41
|
+
@polling_timer.cancel unless @polling_timer.nil?
|
42
|
+
@polling_timer = nil
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
def preset(number)
|
47
|
+
#
|
48
|
+
# Recall Device 0 Preset number 1001
|
49
|
+
# Device Number will always be 0 for Preset strings
|
50
|
+
# 1001 == minimum preset number
|
51
|
+
#
|
52
|
+
do_send('RECALL', 0, 'PRESET', number)
|
53
|
+
end
|
54
54
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
55
|
+
# {1 => [2,3,5], 2 => [2,3,6]}, true
|
56
|
+
# Supports Matrix and Automixers
|
57
|
+
def mixer(id, inouts, mute = false)
|
58
|
+
value = is_affirmative?(mute) ? 1 : 0
|
59
59
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
60
|
+
if inouts.is_a? Hash
|
61
|
+
inouts.each_key do |input|
|
62
|
+
outputs = inouts[input]
|
63
|
+
outs = outputs.is_a?(Array) ? outputs : [outputs]
|
64
64
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
def fader(fader_id, level, index = 1)
|
77
|
-
# value range: -100 ~ 12
|
78
|
-
do_send('SETD', self[:device_id], 'FDRLVL', fader_id, index, level)
|
79
|
-
end
|
80
|
-
|
81
|
-
def mute(fader_id, val = true, index = 1)
|
82
|
-
actual = val ? 1 : 0
|
83
|
-
do_send('SETD', self[:device_id], 'FDRMUTE', fader_id, index, actual)
|
84
|
-
end
|
85
|
-
|
86
|
-
def unmute(fader_id, index = 1)
|
87
|
-
mute(fader_id, false, index)
|
88
|
-
end
|
65
|
+
outs.each do |output|
|
66
|
+
do_send('SETD', self[:device_id], 'MMMUTEXP', id, input, output, value)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
else # assume array (auto-mixer)
|
70
|
+
inouts.each do |input|
|
71
|
+
do_send('SETD', self[:device_id], 'AMMUTEXP', id, input, value)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
89
75
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
end
|
76
|
+
FADERS = {
|
77
|
+
fader: 'FDRLVL',
|
78
|
+
matrix_in: 'MMLVLIN',
|
79
|
+
matrix_out: 'MMLVLOUT',
|
80
|
+
matrix_crosspoint: 'MMLVLXP'
|
81
|
+
}
|
82
|
+
|
83
|
+
def fader(fader_id, level, index = 1, type = :level_fader)
|
84
|
+
fad_type = FADERS[type.to_sym]
|
100
85
|
|
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
|
-
|
86
|
+
# value range: -100 ~ 12
|
87
|
+
faders = fader_id.is_a?(Array) ? fader_id : [fader_id]
|
88
|
+
faders.each do |fad|
|
89
|
+
do_send('SETD', self[:device_id], fad_type, fad, index, level)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def mute(fader_id, val = true, index = 1)
|
94
|
+
actual = val ? 1 : 0
|
95
|
+
faders = fader_id.is_a?(Array) ? fader_id : [fader_id]
|
96
|
+
faders.each do |fad|
|
97
|
+
do_send('SETD', self[:device_id], 'FDRMUTE', fad, index, actual)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def unmute(fader_id, index = 1)
|
102
|
+
mute(fader_id, false, index)
|
103
|
+
end
|
104
|
+
|
105
|
+
def query_fader(fader_id, index = 1)
|
106
|
+
fad = fader_id.is_a?(Array) ? fader_id[0] : fader_id
|
107
|
+
|
108
|
+
send("GET #{self[:device_id]} FDRLVL #{fad} #{index} \n") do |data|
|
109
|
+
if data.start_with?('-ERR')
|
110
|
+
:abort
|
111
|
+
else
|
112
|
+
self[:"fader#{fad}_#{index}"] = data.to_i
|
113
|
+
:success
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def query_mute(fader_id, index = 1)
|
119
|
+
fad = fader_id.is_a?(Array) ? fader_id[0] : fader_id
|
120
|
+
|
121
|
+
send("GET #{self[:device_id]} FDRMUTE #{fad} #{index} \n") do |data|
|
122
|
+
if data.start_with?('-ERR')
|
123
|
+
:abort
|
124
|
+
else
|
125
|
+
self[:"fader#{fad}_#{index}_mute"] = data.to_i == 1
|
126
|
+
:success
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
|
132
|
+
def received(data, resolve, command)
|
133
|
+
if data.start_with?('-ERR')
|
134
|
+
logger.debug "Nexia returned #{data} for #{command[:data]}" if command
|
135
|
+
return :abort
|
136
|
+
end
|
137
|
+
|
138
|
+
#--> "#SETD 0 FDRLVL 29 1 0.000000 +OK"
|
139
|
+
data = data.split(' ')
|
140
|
+
unless data[2].nil?
|
141
|
+
case data[2].to_sym
|
142
|
+
when :FDRLVL, :VL
|
143
|
+
self[:"fader#{data[3]}_#{data[4]}"] = data[5].to_i
|
144
|
+
when :FDRMUTE
|
145
|
+
self[:"fader#{data[3]}_#{data[4]}_mute"] = data[5] == "1"
|
146
|
+
when :DEVID
|
147
|
+
# "#GETD 0 DEVID 1 "
|
148
|
+
self[:device_id] = data[-2].to_i
|
149
|
+
when :MMLVLIN
|
150
|
+
self[:"matrix_in#{data[3]}_#{data[4]}"] = data[5].to_i
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
return :success
|
155
|
+
end
|
156
|
+
|
157
|
+
|
158
|
+
|
159
|
+
private
|
160
|
+
|
161
|
+
|
162
|
+
def do_send(*args)
|
163
|
+
send("#{args.join(' ')} \n")
|
164
|
+
end
|
144
165
|
end
|
145
166
|
|
data/modules/bss/blu100.rb
CHANGED
@@ -6,7 +6,7 @@ class Bss::Blu100
|
|
6
6
|
include ::Orchestrator::Constants
|
7
7
|
include ::Orchestrator::Transcoder
|
8
8
|
|
9
|
-
|
9
|
+
def on_load
|
10
10
|
defaults({
|
11
11
|
:wait => false
|
12
12
|
})
|
@@ -17,14 +17,14 @@ class Bss::Blu100
|
|
17
17
|
})
|
18
18
|
|
19
19
|
on_update
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
20
|
+
end
|
21
|
+
|
22
|
+
def on_unload
|
23
|
+
end
|
24
|
+
|
25
|
+
def on_update
|
26
26
|
@type_lookup ||= {}
|
27
|
-
|
27
|
+
end
|
28
28
|
|
29
29
|
def connected
|
30
30
|
subscribe_percent(1, 60000)
|
data/modules/chiyu/cyt.rb
CHANGED
@@ -30,13 +30,18 @@ class Chiyu::Cyt
|
|
30
30
|
def on_update
|
31
31
|
end
|
32
32
|
|
33
|
-
# No keep alive required as the device polls us
|
34
33
|
def connected
|
35
34
|
do_send(:state)
|
36
35
|
do_send(:auto_report)
|
36
|
+
|
37
|
+
@polling_timer = schedule.every('60s') do
|
38
|
+
do_send(:state)
|
39
|
+
end
|
37
40
|
end
|
38
41
|
|
39
42
|
def disconnected
|
43
|
+
@polling_timer.cancel unless @polling_timer.nil?
|
44
|
+
@polling_timer = nil
|
40
45
|
end
|
41
46
|
|
42
47
|
|
data/modules/clipsal/c_bus.rb
CHANGED
@@ -3,13 +3,13 @@ module Clipsal; end
|
|
3
3
|
|
4
4
|
#
|
5
5
|
# Common Headers
|
6
|
-
#
|
7
|
-
#
|
8
|
-
#
|
6
|
+
# 0x03 == point - point -multipoint, low pri
|
7
|
+
# 0x05 == point - multipoint, low pri
|
8
|
+
# 0x06 == point - point, low pri
|
9
9
|
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
10
|
+
# 11xxx110 (x == reserved)
|
11
|
+
# -- Priority, 11 == high, 00 == low
|
12
|
+
# --- Destination, 011 = P-P-M, 101 = P-M, 110 = P-P
|
13
13
|
#
|
14
14
|
#
|
15
15
|
# Commands are formatted as: \ + Header + 00 + Data + checksum + <cr>
|
@@ -22,235 +22,233 @@ module Clipsal; end
|
|
22
22
|
|
23
23
|
|
24
24
|
class Clipsal::CBus
|
25
|
-
|
25
|
+
include ::Orchestrator::Constants
|
26
26
|
include ::Orchestrator::Transcoder
|
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
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
#logger.debug "CBus module sent #{string}"
|
254
|
-
end
|
27
|
+
|
28
|
+
def on_load
|
29
|
+
defaults({
|
30
|
+
wait: false,
|
31
|
+
delay: 100 # NOTE:: maybe too much?
|
32
|
+
})
|
33
|
+
|
34
|
+
config({
|
35
|
+
tokenize: true,
|
36
|
+
delimiter: "\x0D"
|
37
|
+
})
|
38
|
+
end
|
39
|
+
|
40
|
+
def on_unload
|
41
|
+
end
|
42
|
+
|
43
|
+
def on_update
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
def connected
|
49
|
+
send("|||\r", priority: 99) # Ensure we are in smart mode
|
50
|
+
@polling_timer = schedule.every('60s') do
|
51
|
+
logger.debug "-- Polling CBUS"
|
52
|
+
send("|||\r", priority: 99) # Ensure we are in smart mode
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def disconnected
|
57
|
+
@polling_timer.cancel unless @polling_timer.nil?
|
58
|
+
@polling_timer = nil
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
def lighting(group, state, application = 0x38)
|
63
|
+
group = group & 0xFF
|
64
|
+
application = application & 0xFF
|
65
|
+
|
66
|
+
command = [0x05, application, 0x00]
|
67
|
+
if [On, 1, :on, 'on'].include?(state)
|
68
|
+
state = On
|
69
|
+
command << 0x79 # Group on
|
70
|
+
else
|
71
|
+
state = Off
|
72
|
+
command << 0x01 # Group off
|
73
|
+
end
|
74
|
+
command << group
|
75
|
+
|
76
|
+
self["lighting_group_#{group}"] = state
|
77
|
+
|
78
|
+
do_send(command)
|
79
|
+
end
|
80
|
+
|
81
|
+
|
82
|
+
def lighting_ramp(group, level, rate = 0b0001, application = 0x38)
|
83
|
+
|
84
|
+
#
|
85
|
+
# rates:
|
86
|
+
# => 0 == instant
|
87
|
+
# => 1 == 4sec
|
88
|
+
# => 2 == 8sec etc
|
89
|
+
#
|
90
|
+
rate = ((rate & 0x0F) << 3) | 0b010 # The command is structured as: 0b0 xxxx 010 where xxxx == rate
|
91
|
+
group = group & 0xFF
|
92
|
+
level = level & 0xFF
|
93
|
+
application = application & 0xFF
|
94
|
+
|
95
|
+
lighting_term_ramp(group)
|
96
|
+
command = [0x05, application, 0x00, rate, group, level]
|
97
|
+
|
98
|
+
do_send(command)
|
99
|
+
end
|
100
|
+
|
101
|
+
|
102
|
+
|
103
|
+
def blinds(group, action, application = 0x38)
|
104
|
+
group = group & 0xFF
|
105
|
+
application = application & 0xFF
|
106
|
+
|
107
|
+
command = [0x05, application, 0x00]
|
108
|
+
if is_affirmative?(action)
|
109
|
+
action = Down
|
110
|
+
command += [0x1A, group, 0x00]
|
111
|
+
else
|
112
|
+
command += [0x02, group]
|
113
|
+
|
114
|
+
if is_negatory?(action)
|
115
|
+
action = Up
|
116
|
+
command << 0xFF
|
117
|
+
else
|
118
|
+
# Stop (need to confirm this)
|
119
|
+
command << 0x05
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
do_send(command)
|
124
|
+
end
|
125
|
+
|
126
|
+
|
127
|
+
def trigger(group, action)
|
128
|
+
group = group.to_i & 0xFF
|
129
|
+
action = action.to_i & 0xFF
|
130
|
+
command = [0x05, 0xCA, 0x00, 0x02, group, action]
|
131
|
+
|
132
|
+
self["trigger_group_#{group}"] = action
|
133
|
+
|
134
|
+
do_send(command)
|
135
|
+
end
|
136
|
+
|
137
|
+
|
138
|
+
def trigger_kill(group)
|
139
|
+
group = group.to_i
|
140
|
+
|
141
|
+
group = group & 0xFF
|
142
|
+
command = [0x05, 0xCA, 0x00, 0x01, group]
|
143
|
+
do_send(command)
|
144
|
+
end
|
145
|
+
|
146
|
+
|
147
|
+
def received(data, resolve, command)
|
148
|
+
# Debug here will sometimes have the \n char
|
149
|
+
# This is removed by the hex_to_byte function
|
150
|
+
logger.debug "CBus sent #{data}"
|
151
|
+
|
152
|
+
data = str_to_array(hex_to_byte(data))
|
153
|
+
|
154
|
+
if !check_checksum(data)
|
155
|
+
logger.debug "CBus checksum failed"
|
156
|
+
return :failed
|
157
|
+
end
|
158
|
+
|
159
|
+
# We are only looking at Point -> MultiPoint commands
|
160
|
+
return if data[0] != 0x05
|
161
|
+
# 0x03 == Point -> Point -> MultiPoint
|
162
|
+
# 0x06 == Point -> Point
|
163
|
+
|
164
|
+
application = data[2] # The application being referenced
|
165
|
+
commands = data[4..-2] # Remove the header + checksum
|
166
|
+
|
167
|
+
while commands.length > 0
|
168
|
+
current = commands.shift
|
169
|
+
|
170
|
+
case application
|
171
|
+
when 0xCA # Trigger group
|
172
|
+
case current
|
173
|
+
when 0x02 # Trigger Event (ex: 0504CA00 020101 29)
|
174
|
+
self["trigger_group_#{commands.shift}"] = commands.shift # Action selector
|
175
|
+
when 0x01 # Trigger Min
|
176
|
+
self["trigger_group_#{commands.shift}"] = 0
|
177
|
+
when 0x79 # Trigger Max
|
178
|
+
self["trigger_group_#{commands.shift}"] = 0xFF
|
179
|
+
when 0x09 # Indicator Kill (ex: 0504CA00 0901 23)
|
180
|
+
commands.shift # Group (turns off indicators of all scenes triggered by this group)
|
181
|
+
else
|
182
|
+
break # We don't know what data is here
|
183
|
+
end
|
184
|
+
when 0x30..0x5F # Lighting group
|
185
|
+
case current
|
186
|
+
when 0x01 # Group off (ex: 05043800 0101 0102 0103 0104 7905 33)
|
187
|
+
self["lighting_group_#{commands.shift}"] = Off
|
188
|
+
when 0x79 # Group on (ex: 05013800 7905 44)
|
189
|
+
self["lighting_group_#{commands.shift}"] = On
|
190
|
+
when 0x02 # Blinds up or stop
|
191
|
+
group = commands.shift
|
192
|
+
value = commands.shift
|
193
|
+
if value == 0xFF
|
194
|
+
self["blinds_group_#{group}"] = Up
|
195
|
+
elsif value == 0x05 # Value needs confirmation
|
196
|
+
self["blinds_group_#{group}"] = :stopped
|
197
|
+
end
|
198
|
+
when 0x1A # Blinds down
|
199
|
+
group = commands.shift
|
200
|
+
value = commands.shift
|
201
|
+
self["blinds_group_#{group}"] = Down if value == 0x00
|
202
|
+
when 0x09 # Terminate Ramp
|
203
|
+
commands.shift # Group address
|
204
|
+
else
|
205
|
+
if (current & 0b10000101) == 0 # Ramp to level (ex: 05013800 0205FF BC)
|
206
|
+
commands.shift(2) # Group address, level
|
207
|
+
else
|
208
|
+
break # We don't know what data is here
|
209
|
+
end
|
210
|
+
end
|
211
|
+
else
|
212
|
+
break # We haven't programmed this application
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
return :success
|
217
|
+
end
|
218
|
+
|
219
|
+
|
220
|
+
protected
|
221
|
+
|
222
|
+
|
223
|
+
def lighting_term_ramp(group)
|
224
|
+
command = [0x05, 0x38, 0x00, 0x09, group]
|
225
|
+
do_send(command)
|
226
|
+
end
|
227
|
+
|
228
|
+
|
229
|
+
def checksum(data)
|
230
|
+
check = 0
|
231
|
+
data.each do |byte|
|
232
|
+
check += byte
|
233
|
+
end
|
234
|
+
check = check % 0x100
|
235
|
+
check = ((check ^ 0xFF) + 1) & 0xFF
|
236
|
+
return check
|
237
|
+
end
|
238
|
+
|
239
|
+
def check_checksum(data)
|
240
|
+
check = 0
|
241
|
+
data.each do |byte|
|
242
|
+
check += byte
|
243
|
+
end
|
244
|
+
return (check % 0x100) == 0x00
|
245
|
+
end
|
246
|
+
|
247
|
+
|
248
|
+
def do_send(command, options = {})
|
249
|
+
string = byte_to_hex(command << checksum(command)).upcase
|
250
|
+
send("\\#{string}\r", options)
|
251
|
+
#logger.debug "CBus module sent #{string}"
|
252
|
+
end
|
255
253
|
end
|
256
254
|
|