ruby-sml 0.2
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.
- data/LICENSE +24 -0
- data/README.md +0 -0
- data/lib/ruby-sml.rb +30 -0
- data/lib/ruby-sml/crc16.rb +47 -0
- data/lib/ruby-sml/encoding-binary.rb +262 -0
- data/lib/ruby-sml/helpers.rb +58 -0
- data/lib/ruby-sml/nilclass-mixin.rb +5 -0
- data/lib/ruby-sml/obis.rb +139 -0
- data/lib/ruby-sml/sml-attention.rb +60 -0
- data/lib/ruby-sml/sml-file.rb +37 -0
- data/lib/ruby-sml/sml-getlist.rb +88 -0
- data/lib/ruby-sml/sml-getprocparameter.rb +61 -0
- data/lib/ruby-sml/sml-getprofilelist.rb +103 -0
- data/lib/ruby-sml/sml-getprofilepack.rb +107 -0
- data/lib/ruby-sml/sml-listentry.rb +98 -0
- data/lib/ruby-sml/sml-message.rb +87 -0
- data/lib/ruby-sml/sml-messagebody.rb +95 -0
- data/lib/ruby-sml/sml-periodentry.rb +38 -0
- data/lib/ruby-sml/sml-procparametervalue.rb +46 -0
- data/lib/ruby-sml/sml-profileobjectheaderentry.rb +31 -0
- data/lib/ruby-sml/sml-profileobjectperiodentry.rb +46 -0
- data/lib/ruby-sml/sml-publicclose.rb +51 -0
- data/lib/ruby-sml/sml-publicopen.rb +84 -0
- data/lib/ruby-sml/sml-setprocparameter.rb +37 -0
- data/lib/ruby-sml/sml-time.rb +46 -0
- data/lib/ruby-sml/sml-tree.rb +42 -0
- data/lib/ruby-sml/sml-treepath.rb +24 -0
- data/lib/ruby-sml/sml-tupelentry.rb +105 -0
- data/lib/ruby-sml/sml-valueentry.rb +29 -0
- data/lib/ruby-sml/transport-binary.rb +158 -0
- data/lib/ruby-sml/units.rb +84 -0
- data/sample.rb +66 -0
- metadata +85 -0
data/LICENSE
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
Copyright (c) 2011, Prof. MAAD
|
2
|
+
All rights reserved.
|
3
|
+
|
4
|
+
Redistribution and use in source and binary forms, with or without
|
5
|
+
modification, are permitted provided that the following conditions are met:
|
6
|
+
* Redistributions of source code must retain the above copyright
|
7
|
+
notice, this list of conditions and the following disclaimer.
|
8
|
+
* Redistributions in binary form must reproduce the above copyright
|
9
|
+
notice, this list of conditions and the following disclaimer in the
|
10
|
+
documentation and/or other materials provided with the distribution.
|
11
|
+
* Neither the name of the <organization> nor the
|
12
|
+
names of its contributors may be used to endorse or promote products
|
13
|
+
derived from this software without specific prior written permission.
|
14
|
+
|
15
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
16
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
17
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
18
|
+
DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
19
|
+
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
20
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
21
|
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
22
|
+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
23
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
24
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README.md
ADDED
File without changes
|
data/lib/ruby-sml.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
$:.unshift File.dirname(__FILE__)
|
2
|
+
|
3
|
+
require 'ruby-sml/transport-binary'
|
4
|
+
require 'ruby-sml/encoding-binary'
|
5
|
+
|
6
|
+
require 'ruby-sml/sml-attention'
|
7
|
+
require 'ruby-sml/sml-file'
|
8
|
+
require 'ruby-sml/sml-getlist'
|
9
|
+
require 'ruby-sml/sml-getprocparameter'
|
10
|
+
require 'ruby-sml/sml-getprofilelist'
|
11
|
+
require 'ruby-sml/sml-getprofilepack'
|
12
|
+
require 'ruby-sml/sml-listentry'
|
13
|
+
require 'ruby-sml/sml-messagebody'
|
14
|
+
require 'ruby-sml/sml-message'
|
15
|
+
require 'ruby-sml/sml-periodentry'
|
16
|
+
require 'ruby-sml/sml-procparametervalue'
|
17
|
+
require 'ruby-sml/sml-profileobjectheaderentry'
|
18
|
+
require 'ruby-sml/sml-profileobjectperiodentry'
|
19
|
+
require 'ruby-sml/sml-publicclose'
|
20
|
+
require 'ruby-sml/sml-publicopen'
|
21
|
+
require 'ruby-sml/sml-setprocparameter'
|
22
|
+
require 'ruby-sml/sml-time'
|
23
|
+
require 'ruby-sml/sml-treepath'
|
24
|
+
require 'ruby-sml/sml-tree'
|
25
|
+
require 'ruby-sml/sml-tupelentry'
|
26
|
+
require 'ruby-sml/sml-valueentry'
|
27
|
+
|
28
|
+
require 'ruby-sml/units'
|
29
|
+
require 'ruby-sml/obis'
|
30
|
+
require 'ruby-sml/helpers'
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# taken from http://www.hadermann.be/blog/32/ruby-crc16-implementation/
|
2
|
+
|
3
|
+
module CRC16
|
4
|
+
|
5
|
+
def self.crc16(buf, crc=0xffff)
|
6
|
+
buf.each_byte{|x| crc = (crc >> 8) ^ CCITT_16[(crc ^ x) & 0xff]}
|
7
|
+
return crc
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
CCITT_16 = [
|
13
|
+
0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
|
14
|
+
0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
|
15
|
+
0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
|
16
|
+
0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
|
17
|
+
0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
|
18
|
+
0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
|
19
|
+
0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
|
20
|
+
0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
|
21
|
+
0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
|
22
|
+
0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
|
23
|
+
0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
|
24
|
+
0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
|
25
|
+
0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
|
26
|
+
0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
|
27
|
+
0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
|
28
|
+
0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
|
29
|
+
0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
|
30
|
+
0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
|
31
|
+
0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
|
32
|
+
0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
|
33
|
+
0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
|
34
|
+
0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
|
35
|
+
0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
|
36
|
+
0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
|
37
|
+
0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
|
38
|
+
0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
|
39
|
+
0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
|
40
|
+
0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
|
41
|
+
0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
|
42
|
+
0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
|
43
|
+
0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
|
44
|
+
0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
|
45
|
+
]
|
46
|
+
|
47
|
+
end
|
@@ -0,0 +1,262 @@
|
|
1
|
+
module SML
|
2
|
+
|
3
|
+
class BinaryEncoding
|
4
|
+
|
5
|
+
def self.decode_file(file)
|
6
|
+
source = String.new(file)
|
7
|
+
sml_file = []
|
8
|
+
position = 0
|
9
|
+
|
10
|
+
list_length = []
|
11
|
+
list_depth = 0
|
12
|
+
parent = []
|
13
|
+
current_list = sml_file
|
14
|
+
|
15
|
+
while not source.empty?
|
16
|
+
type = nil
|
17
|
+
value = nil
|
18
|
+
header_length = 0
|
19
|
+
length = 0
|
20
|
+
tl_byte = source.slice!(0,1).unpack('C')[0]
|
21
|
+
break if tl_byte.nil?
|
22
|
+
|
23
|
+
# check for special cases
|
24
|
+
if tl_byte == 0x00
|
25
|
+
# puts "end of message"
|
26
|
+
# puts "--------------"
|
27
|
+
list_length = []
|
28
|
+
list_depth = 0
|
29
|
+
|
30
|
+
current_list << :end_of_message
|
31
|
+
|
32
|
+
current_list = sml_file
|
33
|
+
parent = []
|
34
|
+
|
35
|
+
next
|
36
|
+
end
|
37
|
+
if tl_byte == 0x01
|
38
|
+
# list_depth.times do print "\t" end
|
39
|
+
# puts "?"
|
40
|
+
|
41
|
+
current_list << nil
|
42
|
+
|
43
|
+
if not list_length.empty?
|
44
|
+
l = list_length.pop
|
45
|
+
l -= 1
|
46
|
+
list_length.push(l)
|
47
|
+
end
|
48
|
+
while list_length.last == 0
|
49
|
+
list_length.pop
|
50
|
+
list_depth -= 1
|
51
|
+
current_list = parent.pop
|
52
|
+
end
|
53
|
+
|
54
|
+
next
|
55
|
+
end
|
56
|
+
|
57
|
+
# parse tl field
|
58
|
+
type_bits = (tl_byte & 0b01110000) >> 4
|
59
|
+
case type_bits
|
60
|
+
when 0b000
|
61
|
+
type = :string
|
62
|
+
when 0b100
|
63
|
+
type = :bool
|
64
|
+
when 0b101
|
65
|
+
type = :signed
|
66
|
+
when 0b110
|
67
|
+
type = :unsigned
|
68
|
+
when 0b111
|
69
|
+
type = :list
|
70
|
+
else
|
71
|
+
type = nil
|
72
|
+
# puts "type: unknown (0b#{type_bits.to_s(2)})"
|
73
|
+
exit
|
74
|
+
end
|
75
|
+
|
76
|
+
list_depth.times do
|
77
|
+
# print "\t"
|
78
|
+
end
|
79
|
+
|
80
|
+
if not list_length.empty?
|
81
|
+
l = list_length.pop
|
82
|
+
l -= 1
|
83
|
+
list_length.push(l)
|
84
|
+
end
|
85
|
+
|
86
|
+
length = tl_byte & 0b00001111
|
87
|
+
header_length += 1
|
88
|
+
while (tl_byte & 0b10000000) != 0
|
89
|
+
length = length << 4
|
90
|
+
tl_byte = source.slice!(0,1).unpack('C')[0]
|
91
|
+
length |= (tl_byte & 0b00001111)
|
92
|
+
header_length += 1
|
93
|
+
end
|
94
|
+
|
95
|
+
length -= header_length unless type == :list
|
96
|
+
|
97
|
+
# we know what to expect, lets get it
|
98
|
+
case type
|
99
|
+
when :string
|
100
|
+
value = source.slice!(0,length)
|
101
|
+
# puts "string(#{length}): #{value}"
|
102
|
+
current_list << value
|
103
|
+
when :bool
|
104
|
+
value = source.slice!(0,1).unpack('C')[0]
|
105
|
+
if value == 0
|
106
|
+
value = false
|
107
|
+
else
|
108
|
+
value = true
|
109
|
+
end
|
110
|
+
# puts "bool: #{value}"
|
111
|
+
current_list << value << :bool
|
112
|
+
when :signed
|
113
|
+
value = 0
|
114
|
+
bytes_left = length
|
115
|
+
while bytes_left > 0
|
116
|
+
byte = source.slice!(0,1).unpack('C')[0]
|
117
|
+
value = value << 8
|
118
|
+
value |= byte
|
119
|
+
bytes_left -= 1
|
120
|
+
end
|
121
|
+
value = to_signed(value, length*8)
|
122
|
+
# puts "int#{length*8}: #{value}"
|
123
|
+
current_list << value << "int#{length*8}".to_sym
|
124
|
+
when :unsigned
|
125
|
+
value = 0
|
126
|
+
bytes_left = length
|
127
|
+
while bytes_left > 0
|
128
|
+
byte = source.slice!(0,1).unpack('C')[0]
|
129
|
+
value = value << 8
|
130
|
+
value |= byte
|
131
|
+
bytes_left -= 1
|
132
|
+
end
|
133
|
+
# puts "uint#{length*8}: #{value}"
|
134
|
+
current_list << value << "uint#{length*8}".to_sym
|
135
|
+
when :list
|
136
|
+
# puts "list: #{length} elements"
|
137
|
+
list_depth += 1
|
138
|
+
list_length.push(length)
|
139
|
+
new_list = []
|
140
|
+
current_list << new_list
|
141
|
+
parent.push(current_list)
|
142
|
+
current_list = new_list
|
143
|
+
end
|
144
|
+
|
145
|
+
while list_length.last == 0
|
146
|
+
list_length.pop
|
147
|
+
list_depth -= 1
|
148
|
+
current_list = parent.pop
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
return sml_file
|
153
|
+
end
|
154
|
+
|
155
|
+
def self.encode_file(file)
|
156
|
+
result = String.new
|
157
|
+
|
158
|
+
array_rep = Array.new(file)
|
159
|
+
array_rep.each do |message|
|
160
|
+
result << encode_value(message, :array) << 0x00
|
161
|
+
end
|
162
|
+
|
163
|
+
return result
|
164
|
+
end
|
165
|
+
|
166
|
+
def self.encode_value(value, type)
|
167
|
+
result = String.new
|
168
|
+
|
169
|
+
case type
|
170
|
+
when :array
|
171
|
+
entries_with_type = []
|
172
|
+
while not value.empty?
|
173
|
+
entry = value.shift
|
174
|
+
type = case entry
|
175
|
+
when Array
|
176
|
+
:array
|
177
|
+
when String
|
178
|
+
:string
|
179
|
+
when NilClass
|
180
|
+
:nil
|
181
|
+
when Fixnum
|
182
|
+
value.shift
|
183
|
+
end
|
184
|
+
|
185
|
+
entries_with_type << [entry, type]
|
186
|
+
end
|
187
|
+
|
188
|
+
tl_bytes = encode_length(entries_with_type.length, false)
|
189
|
+
tl_bytes[0] = 0b01110000 + tl_bytes[0]
|
190
|
+
tl_bytes.each do |byte|
|
191
|
+
result << byte
|
192
|
+
end
|
193
|
+
entries_with_type.each do |entry, type|
|
194
|
+
result << encode_value(entry,type)
|
195
|
+
end
|
196
|
+
when :string
|
197
|
+
tl_bytes = encode_length(value.length, true)
|
198
|
+
tl_bytes[0] = 0b00000000 + tl_bytes[0]
|
199
|
+
tl_bytes.each do |byte|
|
200
|
+
result << byte
|
201
|
+
end
|
202
|
+
result << value
|
203
|
+
when :int8
|
204
|
+
result << 0x52 << [value].pack('c')
|
205
|
+
when :int16
|
206
|
+
result << 0x53
|
207
|
+
result << [value].pack('s').reverse
|
208
|
+
when :int32
|
209
|
+
result << 0x55
|
210
|
+
result << [value].pack('l').reverse
|
211
|
+
when :int64
|
212
|
+
result << 0x59
|
213
|
+
result << [value].pack('q').reverse
|
214
|
+
when :uint8
|
215
|
+
result << 0x62 << [value].pack('C')
|
216
|
+
when :uint16
|
217
|
+
result << 0x63 << [value].pack('n')
|
218
|
+
when :uint32
|
219
|
+
result << 0x65 << [value].pack('N')
|
220
|
+
when :uint64
|
221
|
+
result << 0x69 << [value].pack('Q').reverse
|
222
|
+
when :bool
|
223
|
+
if value == 0
|
224
|
+
result << 0x42 << 0x00
|
225
|
+
else
|
226
|
+
result << 0x42 << 0x01
|
227
|
+
end
|
228
|
+
when :nil
|
229
|
+
result << 0x01
|
230
|
+
end
|
231
|
+
|
232
|
+
return result
|
233
|
+
end
|
234
|
+
def self.encode_length(length, include_header)
|
235
|
+
result = []
|
236
|
+
|
237
|
+
header_length = 1
|
238
|
+
while (length+(include_header ? header_length : 0)) >= 2**(4*header_length)
|
239
|
+
header_length += 1
|
240
|
+
end
|
241
|
+
total_length = length + (include_header ? header_length : 0)
|
242
|
+
|
243
|
+
while header_length > 0
|
244
|
+
mask = 0xf << (header_length-1)*4
|
245
|
+
if header_length > 1
|
246
|
+
result << (0b10000000 | ((total_length & mask) >> (header_length-1)*4))
|
247
|
+
else
|
248
|
+
result << ((total_length & mask) >> (header_length-1)*4)
|
249
|
+
end
|
250
|
+
header_length -= 1
|
251
|
+
end
|
252
|
+
|
253
|
+
return result
|
254
|
+
end
|
255
|
+
|
256
|
+
def self.to_signed(int, bits)
|
257
|
+
mask = (1 << (bits - 1))
|
258
|
+
return (int & ~mask) - (int & mask)
|
259
|
+
end
|
260
|
+
|
261
|
+
end
|
262
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'ruby-sml/sml-listentry'
|
2
|
+
require 'ruby-sml/sml-periodentry'
|
3
|
+
require 'ruby-sml/sml-tree'
|
4
|
+
|
5
|
+
require 'ruby-sml/obis.rb'
|
6
|
+
|
7
|
+
module SML
|
8
|
+
|
9
|
+
module Helpers
|
10
|
+
|
11
|
+
def self.hex_to_s(hex)
|
12
|
+
result = ""
|
13
|
+
hex.each_byte do |byte|
|
14
|
+
result << byte.to_s(16) << ":"
|
15
|
+
end
|
16
|
+
result.slice!(-1)
|
17
|
+
|
18
|
+
return result
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.print_entry(entry)
|
22
|
+
return unless (entry.class == SML::ListEntry or entry.class == SML::PeriodEntry)
|
23
|
+
|
24
|
+
name = entry.name
|
25
|
+
value = entry.value
|
26
|
+
scaler = entry.scaler
|
27
|
+
unit = entry.unit
|
28
|
+
|
29
|
+
name = SML::OBIS::resolve(name)
|
30
|
+
value = value * (10**entry.scaler) if ((value.class == Fixnum) and not (scaler.nil?))
|
31
|
+
value = value.to_f if (value.class == Fixnum)
|
32
|
+
unit = SML::Units[unit]["unit"] unless (unit.nil? or SML::Units[unit].nil?)
|
33
|
+
|
34
|
+
puts "#{name}: #{value} #{unit}"
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.print_tree(tree)
|
38
|
+
return unless tree.class == SML::Tree
|
39
|
+
print_tree_internal(tree, 0)
|
40
|
+
end
|
41
|
+
def self.print_tree_internal(tree, level)
|
42
|
+
name = tree.parameter_name
|
43
|
+
name = SML::OBIS::resolve(name)
|
44
|
+
|
45
|
+
if level > 0
|
46
|
+
(level*4).times do print " " end
|
47
|
+
print "|-> " unless level == 0
|
48
|
+
end
|
49
|
+
puts "#{name} : #{tree.parameter_value}"
|
50
|
+
|
51
|
+
tree.child_list.each do |child|
|
52
|
+
print_tree_internal(child, level+1)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
@@ -0,0 +1,139 @@
|
|
1
|
+
require 'ruby-sml/helpers'
|
2
|
+
|
3
|
+
module SML
|
4
|
+
|
5
|
+
module OBIS
|
6
|
+
|
7
|
+
def self.resolve(obis)
|
8
|
+
if SML::OBIS::Lookup[obis].nil?
|
9
|
+
return SML::Helpers::hex_to_s(obis)
|
10
|
+
else
|
11
|
+
return SML::OBIS::Lookup[obis]
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
Lookup = {}
|
16
|
+
|
17
|
+
Lookup["\x81\x81\xc7\x82\x01\xff"] = "Device Properties Root"
|
18
|
+
Lookup["\x81\x81\xc7\x82\x02\xff"] = "Device Class"
|
19
|
+
Lookup["\x81\x81\xc7\x82\x03\xff"] = "Manufacturer"
|
20
|
+
Lookup["\x81\x81\xc7\x82\x05\xff"] = "Public Key"
|
21
|
+
|
22
|
+
Lookup["\x01\x00\x00\x00\x09\xff"] = "Device ID"
|
23
|
+
Lookup["\x01\x00\x00\x02\x00\xff"] = "Firmware Version"
|
24
|
+
Lookup["\x01\x00\x00\x02\x02\xff"] = "Control Program Nr"
|
25
|
+
|
26
|
+
Lookup["\x81\x81\xc7\x89\xe1\xff"] = "Event Log"
|
27
|
+
Lookup["\x81\x81\xc7\x89\xe2\xff"] = "Event ID"
|
28
|
+
|
29
|
+
Lookup["\x81\x81\xc7\x8c\x01\xff"] = "INFO interface active"
|
30
|
+
Lookup["\x81\x81\xc7\x8c\x02\xff"] = "EDL40 mode"
|
31
|
+
Lookup["\x81\x81\xc7\x8c\x03\xff"] = "Delete old usage values"
|
32
|
+
Lookup["\x81\x81\xc7\x8c\x04\xff"] = "Display old usage values"
|
33
|
+
Lookup["\x81\x81\xc7\x8c\x06\xff"] = "Display Text on INFO display"
|
34
|
+
Lookup["\x81\x81\xc7\x8c\x07\xff"] = "Displayed Tariff Registers Bitmask"
|
35
|
+
Lookup["\x81\x81\xc7\x8c\x08\xff"] = "Advanced Manufacturer Dataset on MSB"
|
36
|
+
Lookup["\x81\x81\xc7\x8c\x09\xff"] = "History Delete via Blinken- Interface enabled"
|
37
|
+
Lookup["\x81\x81\xc7\x8c\x0a\xff"] = "Display PIN Protected enabled"
|
38
|
+
Lookup["\x81\x81\xc7\x8c\x0b\xff"] = "Display PIN Code"
|
39
|
+
Lookup["\x81\x81\xc7\x8c\x0c\xff"] = "Number of Manipulation Attempts"
|
40
|
+
Lookup["\x81\x81\xc7\x8c\x0d\xff"] = "Automatic PIN Protected after Timeout enabled"
|
41
|
+
|
42
|
+
Lookup["\x01\x00\x01\x08\x00\xff"] = "Current Value - Overall Register"
|
43
|
+
Lookup["\x01\x00\x01\x08\x01\xff"] = "Current Value - Register Tariff 1"
|
44
|
+
Lookup["\x01\x00\x01\x08\x02\xff"] = "Current Value - Register Tariff 2"
|
45
|
+
Lookup["\x01\x00\x01\x11\x00\xff"] = "Last signed overall Register Value"
|
46
|
+
Lookup["\x01\x00\x0f\x07\x00\xff"] = "Current Meter Reading"
|
47
|
+
|
48
|
+
Lookup["\x01\x00\x01\x08\x00\x60"] = "Usage History - last Day"
|
49
|
+
Lookup["\x01\x00\x01\x08\x00\x61"] = "Usage History - last 7 Days"
|
50
|
+
Lookup["\x01\x00\x01\x08\x00\x62"] = "Usage History - last 30 Days"
|
51
|
+
Lookup["\x01\x00\x01\x08\x00\x63"] = "Usage History - last 365 Days"
|
52
|
+
|
53
|
+
Lookup["\x01\x00\x00\x09\x0b\x00"] = "Current Time"
|
54
|
+
Lookup["\x01\x00\x00\x09\x0b\x01"] = "Former Time"
|
55
|
+
Lookup["\x00\x00\x60\x08\x00\xff"] = "Seconds counter"
|
56
|
+
Lookup["\x81\x00\x00\x09\x0b\x01"] = "Timezone Offset"
|
57
|
+
|
58
|
+
Lookup["\x00\x00\x60\x0e\x00\xff"] = "Selected Tariff"
|
59
|
+
|
60
|
+
Lookup["\x81\x81\x27\x32\x07\x01"] = "Log Entry Period"
|
61
|
+
|
62
|
+
Lookup["\x81\x00\x60\x05\x00\x00"] = "Status word"
|
63
|
+
|
64
|
+
Lookup["\x81\x01\x00\x00\x01\x00"] = "Interface name"
|
65
|
+
Lookup["\x81\x03\x00\x00\x01\x00"] = "Interface name"
|
66
|
+
|
67
|
+
Lookup["\x81\x81\x81\x60\xff\xff"] = "Rights and Roles Root"
|
68
|
+
Lookup["\x81\x81\x81\x60\x01\xff"] = "Role"
|
69
|
+
Lookup["\x81\x81\x81\x60\x02\xff"] = "Role"
|
70
|
+
Lookup["\x81\x81\x81\x60\x03\xff"] = "Role"
|
71
|
+
Lookup["\x81\x81\x81\x60\x04\xff"] = "Role"
|
72
|
+
Lookup["\x81\x81\x81\x60\x05\xff"] = "Role"
|
73
|
+
Lookup["\x81\x81\x81\x60\x06\xff"] = "Role"
|
74
|
+
Lookup["\x81\x81\x81\x60\x07\xff"] = "Role"
|
75
|
+
Lookup["\x81\x81\x81\x60\x08\xff"] = "Role"
|
76
|
+
Lookup["\x81\x81\x81\x60\x01\x01"] = "Access Right" # actualle all of \x81\x81\x81\x60\x0[1-8]\x[01-fe]
|
77
|
+
Lookup["\x81\x81\x81\x61\xff\xff"] = "Username"
|
78
|
+
Lookup["\x81\x81\x81\x62\xff\xff"] = "Password"
|
79
|
+
Lookup["\x81\x81\x81\x63\xff\xff"] = "Public Key for User Access"
|
80
|
+
Lookup["\x81\x81\x81\x64\x01\x01"] = "ACL for Server ID" # actually all ending with \x01 to \xfe
|
81
|
+
|
82
|
+
Lookup["\x81\x02\x00\x07\x00\xff"] = "Enduser Interface Root"
|
83
|
+
Lookup["\x81\x02\x00\x07\x01\xff"] = "Enduser IP Acquisition Method"
|
84
|
+
Lookup["\x81\x02\x17\x07\x00\x01"] = "Enduser manually assigned IP Address"
|
85
|
+
Lookup["\x81\x02\x17\x07\x01\x01"] = "Enduser manually assigned Network Mask"
|
86
|
+
Lookup["\x81\x02\x00\x07\x02\xff"] = "Enduser DHCP Server active"
|
87
|
+
Lookup["\x81\x02\x00\x07\x02\x01"] = "Enduser DHCP Local Netmask"
|
88
|
+
Lookup["\x81\x02\x00\x07\x02\x02"] = "Enduser DHCP Default Gateway"
|
89
|
+
Lookup["\x81\x02\x00\x07\x02\x03"] = "Enduser DHCP DNS Server"
|
90
|
+
Lookup["\x81\x02\x00\x07\x02\x04"] = "Enduser DHCP IP Pool Start"
|
91
|
+
Lookup["\x81\x02\x00\x07\x02\x05"] = "Enduser DHCP IP Pool End"
|
92
|
+
Lookup["\x81\x02\x00\x07\x10\xff"] = "Enduser Interface Status Root"
|
93
|
+
Lookup["\x81\x02\x17\x07\x00\x00"] = "Enduser Current IP Address"
|
94
|
+
|
95
|
+
Lookup["\x81\x04\x00\x06\x00\xff"] = "WAN Interface Status Root"
|
96
|
+
Lookup["\x81\x04\x00\x00\x01\x00"] = "WAN Interface Name"
|
97
|
+
Lookup["\x81\x04\x00\x02\x00\x00"] = "WAN Interface Firmware Version"
|
98
|
+
Lookup["\x81\x04\x00\x07\x00\xff"] = "WAN Interface Parameter Root"
|
99
|
+
Lookup["\x81\x04\x27\x32\x03\x01"] = "WAN Interface automatic Reboot"
|
100
|
+
Lookup["\x81\x42\x64\x3c\x01\x01"] = "WAN Interface Max. Inter Message Timeout"
|
101
|
+
Lookup["\x81\x42\x64\x3c\x01\x02"] = "WAN Interface Max. Timeout from Close-Request to Open-Response"
|
102
|
+
|
103
|
+
Lookup["\x81\x04\x02\x07\x00\xff"] = "GSM Parameter Root"
|
104
|
+
Lookup["\x81\x04\x00\x32\x01\x01"] = "GSM SIM PIN"
|
105
|
+
Lookup["\x81\x04\x00\x32\x04\x01"] = "GSM Provider Selection Method"
|
106
|
+
Lookup["\x81\x04\x00\x32\x08\x01"] = "GSM Bearer Service Type"
|
107
|
+
Lookup["\x81\x04\x00\x32\x09\x01"] = "GSM Quality of Service"
|
108
|
+
Lookup["\x81\x04\x27\x32\x01\x01"] = "GSM Max. Connection Length"
|
109
|
+
Lookup["\x81\x04\x27\x32\x02\x01"] = "GSM Connection Idle Time"
|
110
|
+
Lookup["\x81\x04\x31\x32\x01\x01"] = "GSM Number of Rings until Call pickup"
|
111
|
+
|
112
|
+
Lookup["\x81\x49\x0d\x06\x00\xff"] = "IPT Status Root"
|
113
|
+
Lookup["\x81\x49\x17\x07\x00\x00"] = "IPT Current Master Target IP Address"
|
114
|
+
Lookup["\x81\x49\x1a\x07\x00\x00"] = "IPT Current Master Target Port"
|
115
|
+
Lookup["\x81\x49\x19\x07\x00\x00"] = "IPT Current Master Source Port"
|
116
|
+
Lookup["\x81\x49\x0d\x07\x00\xff"] = "IPT Parameter Root"
|
117
|
+
Lookup["\x81\x49\x0d\x07\x00\x01"] = "IPT Primary Master Root"
|
118
|
+
Lookup["\x81\x49\x17\x07\x00\x01"] = "IPT Primary Master Target IP Address"
|
119
|
+
Lookup["\x81\x49\x1a\x07\x00\x01"] = "IPT Primary Master Target Port"
|
120
|
+
Lookup["\x81\x49\x19\x07\x00\x01"] = "IPT Primary Master Source Port"
|
121
|
+
Lookup["\x81\x49\x63\x3c\x01\x01"] = "IPT Primary Master Username"
|
122
|
+
Lookup["\x81\x49\x63\x3c\x02\x01"] = "IPT Primary Master Password"
|
123
|
+
Lookup["\x81\x49\x0d\x07\x00\x02"] = "IPT Secondary Master Root"
|
124
|
+
Lookup["\x81\x49\x17\x07\x00\x02"] = "IPT Secondary Master Target IP Address"
|
125
|
+
Lookup["\x81\x49\x1a\x07\x00\x02"] = "IPT Secondary Master Target Port"
|
126
|
+
Lookup["\x81\x49\x19\x07\x00\x02"] = "IPT Secondary Master Source Port"
|
127
|
+
Lookup["\x81\x49\x63\x3c\x01\x02"] = "IPT Secondary Master Username"
|
128
|
+
Lookup["\x81\x49\x63\x3c\x02\x02"] = "IPT Secondary Master Password"
|
129
|
+
Lookup["\x81\x48\x27\x32\x06\x01"] = "IPT Connection Retry Timeout"
|
130
|
+
Lookup["\x81\x48\x31\x32\x02\x01"] = "IPT Max. Connection Retries"
|
131
|
+
|
132
|
+
Lookup["\x81\x04\x00\x33\x01\xff"] = "AT-Hayes-Strings Root"
|
133
|
+
Lookup["\x81\x04\x00\x33\x01\x01"] = "AT-Hayes-String after Modem Power-On, before PIN-Entry"
|
134
|
+
Lookup["\x81\x04\x00\x33\x02\x01"] = "AT-Hayes-String after PIN-Entry"
|
135
|
+
Lookup["\x81\x04\x00\x33\x03\x01"] = "AT-Hayes-String GPRS Initialization"
|
136
|
+
|
137
|
+
end
|
138
|
+
|
139
|
+
end
|