aca-device-modules 1.0.4 → 1.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
@@ -24,120 +24,121 @@ module Kramer::Switcher; end
|
|
24
24
|
#
|
25
25
|
|
26
26
|
class Kramer::Switcher::VsHdmi
|
27
|
-
|
27
|
+
include ::Orchestrator::Constants
|
28
28
|
include ::Orchestrator::Transcoder
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
29
|
+
|
30
|
+
def on_load
|
31
|
+
|
32
|
+
#
|
33
|
+
# Setup constants
|
34
|
+
#
|
35
|
+
self[:limits_known] = false
|
36
|
+
|
37
|
+
defaults({
|
38
|
+
:wait => false,
|
39
|
+
:delay => 200
|
40
|
+
})
|
40
41
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
42
|
+
config = ({
|
43
|
+
:inactivity_timeout => 10000 # We wait 10 seconds before the connection is broken (make and break)
|
44
|
+
})
|
45
|
+
end
|
46
|
+
|
47
|
+
def connected
|
48
|
+
#
|
49
|
+
# Get current state of the switcher
|
50
|
+
#
|
51
|
+
get_machine_type
|
52
|
+
end
|
52
53
|
|
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
|
-
|
54
|
+
|
55
|
+
COMMANDS = {
|
56
|
+
:reset_video => 0,
|
57
|
+
:switch_video => 1,
|
58
|
+
:status_video => 5,
|
59
|
+
:define_machine => 62,
|
60
|
+
:identify_machine => 61
|
61
|
+
}
|
62
|
+
|
63
|
+
|
64
|
+
#
|
65
|
+
# Starting at input 1
|
66
|
+
#
|
67
|
+
def switch(map)
|
68
|
+
# instr, inp, outp, machine number
|
69
|
+
# Switch video
|
70
|
+
command = [1, 0x80, 0x80, 0xFF]
|
71
|
+
|
72
|
+
map.each do |input, outputs|
|
73
|
+
outputs = [outputs] unless outputs.class == Array
|
74
|
+
input = input.to_s if input.class == Symbol
|
75
|
+
input = input.to_i if input.class == String
|
76
|
+
outputs.each do |output|
|
77
|
+
command[1] = 0x80 + input
|
78
|
+
command[2] = 0x80 + output
|
79
|
+
outname = :"video#{output}"
|
80
|
+
send(command, name: outname)
|
81
|
+
self[outname] = input
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
alias :switch_video :switch
|
86
|
+
|
87
|
+
def received(data, resolve, command)
|
88
|
+
logger.debug "Kramer sent 0x#{byte_to_hex(data)}"
|
89
|
+
|
90
|
+
data = str_to_array(data)
|
91
|
+
|
92
|
+
return nil if data[0] & 0b1000000 == 0 # Check we are the destination
|
92
93
|
|
93
|
-
|
94
|
-
|
94
|
+
data[1] = data[1] & 0b1111111 # input
|
95
|
+
data[2] = data[2] & 0b1111111 # output
|
95
96
|
|
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
|
-
|
97
|
+
case data[0] & 0b111111
|
98
|
+
when COMMANDS[:define_machine]
|
99
|
+
if data[1] == 1
|
100
|
+
self[:video_inputs] = data[2]
|
101
|
+
elsif data[1] == 2
|
102
|
+
self[:video_outputs] = data[2]
|
103
|
+
end
|
104
|
+
self[:limits_known] = true # Set here in case unsupported
|
105
|
+
when COMMANDS[:status_video]
|
106
|
+
if data[2] == 0 # Then data[1] has been applied to all the outputs
|
107
|
+
logger.debug "Kramer switched #{data[1]} -> All"
|
108
|
+
|
109
|
+
(1..self[:video_outputs]).each do |i|
|
110
|
+
self["video#{i}"] = data[1]
|
111
|
+
end
|
112
|
+
else
|
113
|
+
self["video#{data[2]}"] = data[1]
|
114
|
+
|
115
|
+
logger.debug "Kramer switched #{data[1]} -> #{data[2]}"
|
116
|
+
|
117
|
+
#
|
118
|
+
# As we may not know the max number of inputs if get machine type didn't work
|
119
|
+
#
|
120
|
+
self[:video_inputs] = data[1] if data[1] > self[:video_inputs]
|
121
|
+
self[:video_outputs] = data[2] if data[2] > self[:video_outputs]
|
122
|
+
end
|
123
|
+
when COMMANDS[:identify_machine]
|
124
|
+
logger.debug "Kramer switcher protocol #{data[1]}.#{data[2]}"
|
125
|
+
end
|
126
|
+
|
127
|
+
return :success
|
128
|
+
end
|
129
|
+
|
130
|
+
|
131
|
+
private
|
132
|
+
|
132
133
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
134
|
+
#
|
135
|
+
# No all switchers implement this
|
136
|
+
#
|
137
|
+
def get_machine_type
|
138
|
+
# id com, video
|
139
|
+
command = [62, 0x81, 0x81, 0xFF]
|
140
|
+
send(command, name: :inputs) # num inputs
|
141
|
+
command[1] = 0x82
|
142
|
+
send(command, name: :outputs) # num outputs
|
143
|
+
end
|
143
144
|
end
|
data/modules/nec/display/all.rb
CHANGED
@@ -33,450 +33,447 @@ module Nec::Display; end
|
|
33
33
|
#
|
34
34
|
#
|
35
35
|
class Nec::Display::All
|
36
|
-
|
36
|
+
include ::Orchestrator::Constants
|
37
37
|
include ::Orchestrator::Transcoder
|
38
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
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
send(command, options)
|
480
|
-
end
|
39
|
+
#
|
40
|
+
# Called on module load complete
|
41
|
+
# Alternatively you can use initialize however will
|
42
|
+
# not have access to settings and this is called
|
43
|
+
# soon afterwards
|
44
|
+
#
|
45
|
+
def on_load
|
46
|
+
#
|
47
|
+
# Setup constants
|
48
|
+
#
|
49
|
+
self[:volume_min] = 0
|
50
|
+
self[:brightness_min] = 0
|
51
|
+
self[:contrast_min] = 0
|
52
|
+
#self[:error] = [] TODO!!
|
53
|
+
|
54
|
+
config({
|
55
|
+
tokenize: true,
|
56
|
+
delimiter: "\x0D",
|
57
|
+
encoding: "ASCII-8BIT"
|
58
|
+
})
|
59
|
+
end
|
60
|
+
|
61
|
+
def connected
|
62
|
+
do_poll
|
63
|
+
|
64
|
+
@polling_timer = schedule.every('30s') do
|
65
|
+
logger.debug "-- Polling Display"
|
66
|
+
do_poll
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def disconnected
|
71
|
+
#
|
72
|
+
# Disconnected may be called without calling connected
|
73
|
+
# Hence the check if timer is nil here
|
74
|
+
#
|
75
|
+
@polling_timer.cancel unless @polling_timer.nil?
|
76
|
+
@polling_timer = nil
|
77
|
+
end
|
78
|
+
|
79
|
+
|
80
|
+
#
|
81
|
+
# Power commands
|
82
|
+
#
|
83
|
+
def power(state)
|
84
|
+
message = "C203D6"
|
85
|
+
|
86
|
+
power? do
|
87
|
+
current = self[:power]
|
88
|
+
if is_affirmative?(state)
|
89
|
+
if current == Off
|
90
|
+
message += "0001" # Power On
|
91
|
+
send_checksum(:command, message, {:name => :power})
|
92
|
+
self[:warming] = true
|
93
|
+
self[:power] = On
|
94
|
+
logger.debug "-- NEC LCD, requested to power on"
|
95
|
+
|
96
|
+
power_on_delay
|
97
|
+
mute_status(0)
|
98
|
+
volume_status(0)
|
99
|
+
end
|
100
|
+
else
|
101
|
+
if current == On
|
102
|
+
message += "0004" # Power Off
|
103
|
+
send_checksum(:command, message, {:name => :power})
|
104
|
+
|
105
|
+
self[:power] = Off
|
106
|
+
logger.debug "-- NEC LCD, requested to power off"
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def power?(options = {}, &block)
|
113
|
+
options[:emit] = block if block_given?
|
114
|
+
type = :command
|
115
|
+
message = "01D6"
|
116
|
+
send_checksum(type, message, options)
|
117
|
+
end
|
118
|
+
|
119
|
+
|
120
|
+
#
|
121
|
+
# Input selection
|
122
|
+
#
|
123
|
+
INPUTS = {
|
124
|
+
:vga => 1,
|
125
|
+
:rgbhv => 2,
|
126
|
+
:dvi => 3,
|
127
|
+
:hdmi_set => 4, # Set only?
|
128
|
+
:video1 => 5,
|
129
|
+
:video2 => 6,
|
130
|
+
:svideo => 7,
|
131
|
+
|
132
|
+
:tv => 10,
|
133
|
+
:dvd1 => 12,
|
134
|
+
:option => 13,
|
135
|
+
:dvd2 => 14,
|
136
|
+
:display_port => 15,
|
137
|
+
|
138
|
+
:hdmi => 17
|
139
|
+
}
|
140
|
+
def switch_to(input)
|
141
|
+
input = input.to_sym if input.class == String
|
142
|
+
#self[:target_input] = input
|
143
|
+
|
144
|
+
type = :set_parameter
|
145
|
+
message = OPERATION_CODE[:video_input]
|
146
|
+
message += INPUTS[input].to_s(16).upcase.rjust(4, '0') # Value of input as a hex string
|
147
|
+
|
148
|
+
send_checksum(type, message, {:name => :input})
|
149
|
+
brightness_status(60) # higher status than polling commands - lower than input switching
|
150
|
+
contrast_status(60)
|
151
|
+
|
152
|
+
logger.debug "-- NEC LCD, requested to switch to: #{input}"
|
153
|
+
end
|
154
|
+
|
155
|
+
AUDIO = {
|
156
|
+
:audio1 => 1,
|
157
|
+
:audio2 => 2,
|
158
|
+
:audio3 => 3,
|
159
|
+
:hdmi => 4,
|
160
|
+
:tv => 6,
|
161
|
+
:display_port => 7
|
162
|
+
}
|
163
|
+
def switch_audio(input)
|
164
|
+
input = input.to_sym if input.class == String
|
165
|
+
#self[:target_audio] = input
|
166
|
+
|
167
|
+
type = :set_parameter
|
168
|
+
message = OPERATION_CODE[:audio_input]
|
169
|
+
message += AUDIO[input].to_s(16).upcase.rjust(4, '0') # Value of input as a hex string
|
170
|
+
|
171
|
+
send_checksum(type, message, :name => :audio)
|
172
|
+
mute_status(60) # higher status than polling commands - lower than input switching
|
173
|
+
volume_status(60)
|
174
|
+
|
175
|
+
logger.debug "-- NEC LCD, requested to switch audio to: #{input}"
|
176
|
+
end
|
177
|
+
|
178
|
+
|
179
|
+
#
|
180
|
+
# Auto adjust
|
181
|
+
#
|
182
|
+
def auto_adjust
|
183
|
+
message = OPERATION_CODE[:auto_setup] #"001E" # Page + OP code
|
184
|
+
message += "0001" # Value of input as a hex string
|
185
|
+
|
186
|
+
send_checksum(:set_parameter, message, :delay_on_receive => 4.0)
|
187
|
+
end
|
188
|
+
|
189
|
+
|
190
|
+
#
|
191
|
+
# Value based set parameter
|
192
|
+
#
|
193
|
+
def brightness(val)
|
194
|
+
val = in_range(val.to_i, 100)
|
195
|
+
|
196
|
+
message = OPERATION_CODE[:brightness_status]
|
197
|
+
message += val.to_s(16).upcase.rjust(4, '0') # Value of input as a hex string
|
198
|
+
|
199
|
+
brightness_status
|
200
|
+
send_checksum(:set_parameter, message)
|
201
|
+
send_checksum(:command, '0C') # Save the settings
|
202
|
+
end
|
203
|
+
|
204
|
+
def contrast(val)
|
205
|
+
val = in_range(val.to_i, 100)
|
206
|
+
|
207
|
+
message = OPERATION_CODE[:contrast_status]
|
208
|
+
message += val.to_s(16).upcase.rjust(4, '0') # Value of input as a hex string
|
209
|
+
|
210
|
+
contrast_status
|
211
|
+
send_checksum(:set_parameter, message)
|
212
|
+
send_checksum(:command, '0C') # Save the settings
|
213
|
+
end
|
214
|
+
|
215
|
+
def volume(val)
|
216
|
+
val = in_range(val.to_i, 100)
|
217
|
+
|
218
|
+
message = OPERATION_CODE[:volume_status]
|
219
|
+
message += val.to_s(16).upcase.rjust(4, '0') # Value of input as a hex string
|
220
|
+
|
221
|
+
volume_status
|
222
|
+
send_checksum(:set_parameter, message)
|
223
|
+
send_checksum(:command, '0C') # Save the settings
|
224
|
+
|
225
|
+
self[:audio_mute] = false # audio is unmuted when the volume is set
|
226
|
+
end
|
227
|
+
|
228
|
+
|
229
|
+
def mute_audio
|
230
|
+
message = OPERATION_CODE[:mute_status]
|
231
|
+
message += "0001" # Value of input as a hex string
|
232
|
+
|
233
|
+
send_checksum(:set_parameter, message)
|
234
|
+
|
235
|
+
logger.debug "-- NEC LCD, requested to mute audio"
|
236
|
+
end
|
237
|
+
alias_method :mute, :mute_audio
|
238
|
+
|
239
|
+
def unmute_audio
|
240
|
+
message = OPERATION_CODE[:mute_status]
|
241
|
+
message += "0000" # Value of input as a hex string
|
242
|
+
|
243
|
+
send_checksum(:set_parameter, message)
|
244
|
+
|
245
|
+
logger.debug "-- NEC LCD, requested to unmute audio"
|
246
|
+
end
|
247
|
+
alias_method :unmute, :unmute_audio
|
248
|
+
|
249
|
+
#
|
250
|
+
# LCD Response code
|
251
|
+
#
|
252
|
+
def received(data, resolve, command)
|
253
|
+
#
|
254
|
+
# Check for valid response
|
255
|
+
#
|
256
|
+
if !check_checksum(data)
|
257
|
+
logger.debug "-- NEC LCD, checksum failed for command: #{command[:data]}"
|
258
|
+
logger.debug "-- NEC LCD, response was: #{data}"
|
259
|
+
return false
|
260
|
+
end
|
261
|
+
|
262
|
+
#data = array_to_str(data) # Convert bytes to a string (received like this)
|
263
|
+
|
264
|
+
case MSG_TYPE[data[4]] # Check the MSG_TYPE (B, D or F)
|
265
|
+
when :command_reply
|
266
|
+
#
|
267
|
+
# Power on and off
|
268
|
+
# 8..9 == "00" means no error
|
269
|
+
if data[10..15] == "C203D6" # Means power comamnd
|
270
|
+
if data[8..9] == "00"
|
271
|
+
power_on_delay(0) # wait until the screen has turned on before sending commands (0 == high priority)
|
272
|
+
else
|
273
|
+
logger.info "-- NEC LCD, command failed: #{command[:data]}"
|
274
|
+
logger.info "-- NEC LCD, response was: #{data}"
|
275
|
+
return false # command failed
|
276
|
+
end
|
277
|
+
elsif data[10..13] == "00D6" # Power status response
|
278
|
+
if data[10..11] == "00"
|
279
|
+
if data[23] == '1' # On == 1, Off == 4
|
280
|
+
self[:power] = On
|
281
|
+
else
|
282
|
+
self[:power] = Off
|
283
|
+
self[:warming] = false
|
284
|
+
end
|
285
|
+
#if self[:power_target].nil?
|
286
|
+
# self[:power_target] = self[:power]
|
287
|
+
#elsif self[:power_target] != self[:power]
|
288
|
+
# power(self[:power_target])
|
289
|
+
#end
|
290
|
+
else
|
291
|
+
logger.info "-- NEC LCD, command failed: #{command[:data]}"
|
292
|
+
logger.info "-- NEC LCD, response was: #{data}"
|
293
|
+
return false # command failed
|
294
|
+
end
|
295
|
+
|
296
|
+
end
|
297
|
+
|
298
|
+
when :get_parameter_reply, :set_parameter_reply
|
299
|
+
if data[8..9] == "00"
|
300
|
+
parse_response(data, command)
|
301
|
+
elsif data[8..9] == 'BE' # Wait response
|
302
|
+
send(command[:data]) # checksum already added
|
303
|
+
logger.debug "-- NEC LCD, response was a wait command"
|
304
|
+
else
|
305
|
+
logger.info "-- NEC LCD, get or set failed: #{command[:data]}"
|
306
|
+
logger.info "-- NEC LCD, response was: #{data}"
|
307
|
+
return false
|
308
|
+
end
|
309
|
+
end
|
310
|
+
|
311
|
+
return true # Command success
|
312
|
+
end
|
313
|
+
|
314
|
+
|
315
|
+
def do_poll
|
316
|
+
power?({:priority => 0}) do
|
317
|
+
if self[:power] == On
|
318
|
+
power_on_delay
|
319
|
+
mute_status
|
320
|
+
volume_status
|
321
|
+
brightness_status
|
322
|
+
contrast_status
|
323
|
+
video_input
|
324
|
+
audio_input
|
325
|
+
end
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
|
330
|
+
private
|
331
|
+
|
332
|
+
|
333
|
+
def parse_response(data, command)
|
334
|
+
|
335
|
+
# 14..15 == type (we don't care)
|
336
|
+
max = data[16..19].to_i(16)
|
337
|
+
value = data[20..23].to_i(16)
|
338
|
+
|
339
|
+
case OPERATION_CODE[data[10..13]]
|
340
|
+
when :video_input
|
341
|
+
self[:input] = INPUTS.invert[value]
|
342
|
+
#self[:target_input] = self[:input] if self[:target_input].nil?
|
343
|
+
#switch_to(self[:target_input]) unless self[:input] == self[:target_input]
|
344
|
+
|
345
|
+
when :audio_input
|
346
|
+
self[:audio] = AUDIO.invert[value]
|
347
|
+
#self[:target_audio] = self[:audio] if self[:target_audio].nil?
|
348
|
+
#switch_audio(self[:target_audio]) unless self[:audio] == self[:target_audio]
|
349
|
+
|
350
|
+
when :volume_status
|
351
|
+
self[:volume_max] = max
|
352
|
+
if not self[:audio_mute]
|
353
|
+
self[:volume] = value
|
354
|
+
end
|
355
|
+
|
356
|
+
when :brightness_status
|
357
|
+
self[:brightness_max] = max
|
358
|
+
self[:brightness] = value
|
359
|
+
|
360
|
+
when :contrast_status
|
361
|
+
self[:contrast_max] = max
|
362
|
+
self[:contrast] = value
|
363
|
+
|
364
|
+
when :mute_status
|
365
|
+
self[:audio_mute] = value == 1
|
366
|
+
if(value == 1)
|
367
|
+
self[:volume] = 0
|
368
|
+
else
|
369
|
+
volume_status(0) # high priority
|
370
|
+
end
|
371
|
+
|
372
|
+
when :power_on_delay
|
373
|
+
if value > 0
|
374
|
+
self[:warming] = true
|
375
|
+
schedule.in("#{value}s") do # Prevent any commands being sent until the power on delay is complete
|
376
|
+
power_on_delay
|
377
|
+
end
|
378
|
+
else
|
379
|
+
schedule.in('3s') do # Reactive the interface once the display is online
|
380
|
+
self[:warming] = false # allow access to the display
|
381
|
+
end
|
382
|
+
end
|
383
|
+
when :auto_setup
|
384
|
+
# auto_setup
|
385
|
+
# nothing needed to do here (we are delaying the next command by 4 seconds)
|
386
|
+
else
|
387
|
+
logger.info "-- NEC LCD, unknown response: #{data[10..13]}"
|
388
|
+
logger.info "-- NEC LCD, for command: #{command[:data]}"
|
389
|
+
logger.info "-- NEC LCD, full response was: #{data}"
|
390
|
+
end
|
391
|
+
end
|
392
|
+
|
393
|
+
|
394
|
+
#
|
395
|
+
# Types of messages sent to and from the LCD
|
396
|
+
#
|
397
|
+
MSG_TYPE = {
|
398
|
+
:command => 'A',
|
399
|
+
'B' => :command_reply,
|
400
|
+
:get_parameter => 'C',
|
401
|
+
'D' => :get_parameter_reply,
|
402
|
+
:set_parameter => 'E',
|
403
|
+
'F' => :set_parameter_reply
|
404
|
+
}
|
405
|
+
|
406
|
+
|
407
|
+
OPERATION_CODE = {
|
408
|
+
:video_input => '0060', '0060' => :video_input,
|
409
|
+
:audio_input => '022E', '022E' => :audio_input,
|
410
|
+
:volume_status => '0062', '0062' => :volume_status,
|
411
|
+
:mute_status => '008D', '008D' => :mute_status,
|
412
|
+
:power_on_delay => '02D8', '02D8' => :power_on_delay,
|
413
|
+
:contrast_status => '0012', '0012' => :contrast_status,
|
414
|
+
:brightness_status => '0010', '0010' => :brightness_status,
|
415
|
+
:auto_setup => '001E', '001E' => :auto_setup
|
416
|
+
}
|
417
|
+
#
|
418
|
+
# Automatically creates a callable function for each command
|
419
|
+
# http://blog.jayfields.com/2007/10/ruby-defining-class-methods.html
|
420
|
+
# http://blog.jayfields.com/2008/02/ruby-dynamically-define-method.html
|
421
|
+
#
|
422
|
+
OPERATION_CODE.each_key do |command|
|
423
|
+
define_method command do |*args|
|
424
|
+
priority = 99
|
425
|
+
if args.length > 0
|
426
|
+
priority = args[0]
|
427
|
+
end
|
428
|
+
message = OPERATION_CODE[command]
|
429
|
+
send_checksum(:get_parameter, message, {:priority => priority}) # Status polling is a low priority
|
430
|
+
end
|
431
|
+
end
|
432
|
+
|
433
|
+
|
434
|
+
def check_checksum(data)
|
435
|
+
data = str_to_array(data)
|
436
|
+
|
437
|
+
check = 0
|
438
|
+
#
|
439
|
+
# Loop through the second to the second last element
|
440
|
+
# Delimiter is removed automatically
|
441
|
+
#
|
442
|
+
if data.length >= 2
|
443
|
+
data[1..-2].each do |byte|
|
444
|
+
check = check ^ byte
|
445
|
+
end
|
446
|
+
return check == data[-1] # Check the check sum equals the last element
|
447
|
+
else
|
448
|
+
return true
|
449
|
+
end
|
450
|
+
end
|
451
|
+
|
452
|
+
|
453
|
+
#
|
454
|
+
# Builds the command and creates the checksum
|
455
|
+
#
|
456
|
+
def send_checksum(type, command, options = {})
|
457
|
+
#
|
458
|
+
# build header + command and convert to a byte array
|
459
|
+
#
|
460
|
+
command = "" << 0x02 << command << 0x03
|
461
|
+
command = "0*0#{MSG_TYPE[type]}#{command.length.to_s(16).upcase.rjust(2, '0')}#{command}"
|
462
|
+
command = str_to_array(command)
|
463
|
+
|
464
|
+
#
|
465
|
+
# build checksum
|
466
|
+
#
|
467
|
+
check = 0
|
468
|
+
command.each do |byte|
|
469
|
+
check = check ^ byte
|
470
|
+
end
|
471
|
+
|
472
|
+
command << check # Add checksum
|
473
|
+
command << 0x0D # delimiter required by NEC displays
|
474
|
+
command.insert(0, 0x01) # insert SOH byte (not part of the checksum)
|
475
|
+
|
476
|
+
send(command, options)
|
477
|
+
end
|
481
478
|
end
|
482
479
|
|