-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathIRData.rb
173 lines (145 loc) · 3.77 KB
/
IRData.rb
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
class IRData
@data = []
@format = nil
attr_reader :data, :format
T = {
:aeha => 425,
:nec => 562,
:sony => 600
}
def data_inspect
case @format
when :aeha
data_inspect_aeha
when :nec
data_inspect_nec
when :sony
data_inspect_sony
else
nil
end
end
def self.new_by_str(data, format)
raise "unknown format" if T[format].nil?
case format
when :aeha
return self.new(create_data_aeha(data))
when :nec
return self.new(create_data_nec(data))
when :sony
return self.new(create_data_sony(data))
end
end
private
def initialize(data)
@data = data
@format = format?
@data = FixAlignment(@data, @format)
end
def data_inspect_aeha
data = @data.map{|v| (v / T[:aeha])}
data_bin = ""
data.each_slice(2){|a|
next if a == [8,4]
data_bin << "1" if a == [1,3]
data_bin << "0" if a == [1,1]
# TODO if a == [8,8] REPEAT
}
data_hex = [data_bin].pack("B*").unpack("H*")[0]
datan = data_hex[6..data_hex.length]
datan_ary = datan.each_char.each_slice(2).map{|a| a.join}
datan_rev = [datan].pack("H*").unpack("B*").pack("b*").unpack("H*")[0]
datan_rev_ary = datan_rev.each_char.each_slice(2).map{|a| a.join}
return {
:customer_code => data_hex[0..3],
:parity => data_hex[4],
:data0 => data_hex[5],
:datan => datan,
:datan_ary => datan_ary,
:datan_rev => datan_rev,
:datan_rev_ary => datan_rev_ary,
:data_hex => data_hex
}
end
def data_inspect_nec
data = @data.map{|v| (v / T[:nec])}
data_bin = ""
data.each_slice(2){|a|
next if a == [16,8]
data_bin << "1" if a == [1,3]
data_bin << "0" if a == [1,1]
}
data_hex = [data_bin].pack("B*").unpack("H*")[0]
datan = data_hex[4..data_hex.length]
datan_ary = datan.each_char.each_slice(2).map{|a| a.join}
datan_rev = [datan].pack("H*").unpack("B*").pack("b*").unpack("H*")[0]
datan_rev_ary = datan_rev.each_char.each_slice(2).map{|a| a.join}
return {
:customer_code => data_hex[0..3],
:datan => datan,
:datan_ary => datan_ary,
:datan_rev => datan_rev,
:datan_rev_ary => datan_rev_ary,
:data_hex => data_hex
}
end
def data_inspect_sony
raise 'not implemented yet'
data = @data.map{|v| (v / T[:sony])}
end
def self.create_data_aeha(hexstr)
data = []
data << 8*T[:aeha]
data << 4*T[:aeha]
binstr = [hexstr].pack("H*").unpack("B*")[0]
binstr.each_char{|c|
if c == "0"
data << 1*T[:aeha]
data << 1*T[:aeha]
elsif c == "1"
data << 1*T[:aeha]
data << 3*T[:aeha]
end
}
data << 1*T[:aeha] # Trailer
return data
end
def self.create_data_nec(hexstr)
data = []
data << 16*T[:nec]
data << 8*T[:nec]
binstr = [hexstr].pack("H*").unpack("B*")[0]
binstr.each_char{|c|
if c == "0"
data << 1*T[:nec]
data << 1*T[:nec]
elsif c == "1"
data << 1*T[:nec]
data << 3*T[:nec]
end
}
data << 1*T[:nec] # Trailer
return data
end
def self.create_data_sony(hexstr)
raise 'not implemented yet'
end
def FixAlignment(data, type)
t = T[type]
data.map{|v|((v/t.to_f).round)*t}
end
def check_nec(data)
(data[0] == 16*T[:nec] && data[1] == 8*T[:nec] ) # Leader:16T8T
end
def check_aeha(data)
(data[0] == 8*T[:aeha] && data[1] == 4*T[:aeha]) # Leader:8T4T
end
def check_sony(data)
(data[0] == 4*T[:sony] && data[1] == 1*T[:sony]) # Leader:4T, next data must be started by 1T
end
def format?
return :sony if check_sony FixAlignment(@data, :sony)
return :aeha if check_aeha FixAlignment(@data, :aeha)
return :nec if check_nec FixAlignment(@data, :nec)
end
end